éobg Posted September 7, 2022 Share Posted September 7, 2022 Estou fazendo um traçante para MTA, porem... O dx é criado da ponta da arma "getPedWeaponPuzzlePosition" até o final da bala disparada, como todos sabem, o traçante é um efeito/luz que acompanha a bala. Porem não sei como fazer isso, vi que é com uma interpolação, porem infelizmente eu não sei usar isso, está aqui meu código function OnPlayerFire(w,a,aC,hX,hY,hZ,hE) local sx,sy,sz = getPedWeaponMuzzlePosition(source) Position = {sx,sy,sz,hX,hY,hZ} removeEventHandler("onClientRender",root,onRender) addEventHandler("onClientRender",root,onRender) setTimer ( function() removeEventHandler("onClientRender",root,onRender) end, 100, 1 ) end addEventHandler("onClientPlayerWeaponFire",root,OnPlayerFire) function onRender() if Position then local startX,startY,startZ,endX,endY,endZ = unpack(Position) dxDrawLine3D( startX,startY,startZ,endX,endY,endZ,tocolor(255,162,0,150),2.3) end end Link to comment
Other Languages Moderators Lord Henry Posted September 12, 2022 Other Languages Moderators Share Posted September 12, 2022 (edited) O interpolateBetween é uma função onde você consegue obter o "meio" de dois valores inserindo o começo e o final e especificando qual a posição deste meio entre 0 e 1. Por exemplo: Se você tem a coordenada do início do trajeto da bala e a coordenada do final da bala (coordenada onde ela atingiu), se você especificar o valor 0.5 entre eles em um interpolateBetween, você vai obter a coordenada do meio entre elas. local laserShoots = {} -- Tabela que vai armazenar as infos de cada laser. local contador, limite = 0, 20 -- Índice do laser atual | Número máximo de lasers que este jogador pode ver ao mesmo tempo. -- Ao atingir este limite, os lasers mais antigos serão substituídos pelos novos. Limites altos demais causarão lag. local tamanho, velocidadeLaser = 0.05, 0.16 -- Comprimento do laser | Velocidade do laser. (o tiro real continua na mesma velocidade) function onPlayerShoot(w,a,aC,hX,hY,hZ,hE) local sx, sy, sz = getPedWeaponMuzzlePosition(source) -- Obtém a posição de onde sai o tiro. if (sx) then -- Se o jogador atirou com uma arma de fogo (existe a posição do início do tiro), então: contador = contador + 1 -- Contador de 0 vai pra 1, depois vai pra 2 e assim por diante. if (contador > limite) then -- Se o contador passou do limite, então volta pro 1. contador = 1 end laserShoots[contador] = {0, sx, sy, sz, hX, hY, hZ} -- Adiciona as posições de início e final do tiro. O zero indica a posição do tiro ainda não percorreu seu traçado, 0 é no começo e 1 é no final. end end addEventHandler("onClientPlayerWeaponFire", root, onPlayerShoot) -- Ativa essa função quando algum player atirar. addEventHandler("onClientPedWeaponFire", root, onPlayerShoot) -- Ativa essa função quando algum NPC atirar. (opcional) function renderLaserShoots() for i, tiro in pairs (laserShoots) do -- Para cada tiro faça: local percorrido, startX, startY, startZ, endX, endY, endZ = unpack(tiro) -- Obtém as infos do tiro. percorrido = percorrido + velocidadeLaser -- Adiciona a velocidade ao percorrido. Isso faz com que quanto maior a velocidade, mais o laser percorre a cada frame. if (percorrido > 1) then -- Se o laser chegou ao seu destino, então: laserShoots[i] = nil -- Remove ele da tabela de lasers. else -- Se o laser ainda não chegou no destino, então: laserShoots[i] = {percorrido, startX, startY, startZ, endX, endY, endZ} -- Atualiza a nova posição percorrida do laser na tabela. local px1, py1, pz1, px2, py2, pz2 if (percorrido - tamanho >= 0) then -- Isso serve para dar comprimento ao laser, em vez de ser um ponto, ele será um traço. px1, py1, pz1 = interpolateBetween (startX, startY, startZ, endX, endY, endZ, percorrido - tamanho, "Linear") -- Obtém a posição um pouco atrás do tiro. else px1, py1, pz1 = interpolateBetween (startX, startY, startZ, endX, endY, endZ, 0, "Linear") -- Considera como 0 as posições abaixo de 0 para evitar erros. end if (percorrido + tamanho <= 1) then px2, py2, pz2 = interpolateBetween (startX, startY, startZ, endX, endY, endZ, percorrido + tamanho, "Linear") -- Obtém a posição um pouco na frente do tiro. else px2, py2, pz2 = interpolateBetween (startX, startY, startZ, endX, endY, endZ, 1, "Linear") -- Considera como 1 as posições acima de 1 para evitar erros. end dxDrawLine3D (px1, py1, pz1, px2, py2, pz2, tocolor(0,162,0,150), 2.3) -- Cria um traço entre a posição um pouco na frente e um pouco atrás da posição simulada do tiro com a cor e espessura especificados. (cria o laser) end end end addEventHandler("onClientRender", root, renderLaserShoots) -- Executa essa função a cada frame. Caso queira testar com um NPC: Adicione isso no final do client-side: -- ============ Apenas para testes =========== setTimer (function () for i, thePed in pairs (getElementsByType("ped")) do -- Para cada NPC, faça: if (getElementData (thePed, "autoShot")) then -- Se o NPC tem essa elementData, então: setPedAimTarget (thePed, 2488, -1670, 12.3) -- Faz ele mirar no meio do chão da Grove Street. (se não tiver isso, os lasers não aparecem pois não existe posição final do tiro) setPedControlState (thePed, "fire", true) -- Faz ele ficar atirando. end end end, 500, 1) -- Executa isso meio segundo depois que iniciar este resource. E coloque isso server-side: -- ============== Apenas para testes ================= randomPed = createPed (0, 2510, -1670, 13.55, 90) -- Cria um NPC na Grove Street. giveWeapon (randomPed, 30, 9999, true) -- Dá uma AK-47 com 9999 de munição pra ele. setElementData (randomPed, "autoShot", true) -- Coloca essa data nele só pra diferenciá-lo de outros NPCs. Edited September 13, 2022 by Lord Henry Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now