Jump to content

[HELP] Create Projectile Aim (Rocket)


ReZurrecti0n

Recommended Posts

I'm trying to create a ped that fires a rocket projectile from a normal rocket launcher weapon targeting a player. The issue is the rocket projectile's aim, I don't understand how or where it gets even the base aim from in the first place. Through researching this issue, it is my understanding that the projectile will fire straight forward from its owner (In this case, a ped). However, this doesn't seem to be the case for me, seems the rocket flies into the ground near the ped's feet. I'll post a piece of the code to better understand what is going on:

				local rotation=-math.deg(math.atan2(x-x1,y-y1))-- x y z are the coords of the player or player's vehicle and x1 y1 z1 are the ped's coords
				if(rotation<0)then
					rotation=rotation+360
				end
				setElementRotation(ped,0,0,rotation,"default",true)-- Ped now faces the Player
				setPedControlState(ped,"aim_weapon",true)-- Ped aims the weapon at the Player
				setPedAimTarget(ped,x,y,z)-- Targets the Player
				setPedControlState(ped,"fire",true)-- Fires the Rocket Launcher (Or at least the anim for it anyway)
				if(getPedWeaponSlot(ped)==7)then -- Ped is using the Rocket Launcher weapon (Slot anyways)
					setTimer(function(ped)setPedControlState(ped,"fire",false);end,200,1,ped) -- Just so the animations appear right...
					createProjectile(ped,19,x1,y1,z1+1)-- Attempted to use additional arguments such as projectile rotation at first, then went simple...
				end

The results usually are that the rocket projectiles go into the ground near the ped's feet, in some case, seems to shoot backwards behind the ped even...

So my question is, how exactly would I be able to aim the created rocket projectile to correctly fire at the Player's/Vehicle x y z position?

Link to comment

With the code listed above, if I change the z1+1 to z1+5, then it becomes easier to spot the direction of the rocket projectiles. The rocket projectile fires in this direction: Behind the ped and into the ground. The player/vehicle is in front of the ped, straight ahead, only a few meters or so away. So I've ruled out the direction of the created rocket projectile firing straight forward from the ped in the direction the ped is facing. I am currently toying with the additional arguments such as the projectile's rotation, but not having much luck figuring out how any of this works yet...

Edited by ReZurrecti0n
Link to comment

What I have discovered was that the rocket projectile was actually aimed at what the player's camera was currently pointed at. Even though the creator was the ped. When the creator is a vehicle, it simply just fires straight ahead of where ever the vehicle is rotated at. So this changes everything...

I am aware of the target argument and using heat seekers and does in fact work, but not preferred in my scenario. I'd much rather use rockets that either hit or miss. But you're right about setting the correct rotation arguments is the key. That's going to require some mathematics which is not my strong suit I'm afraid. However, there are some work arounds I still intend to try out:

Switching the camera point to yourself (The target), creating the rocket, then setting the camera back to normal is one, although I suspect it will obviously affect gameplay and not the best choice. Another is just using heat seekers with a target of course

Anyway, I do appreciate the response, ty for helping me out, will inform you how the math attempt goes which is the best way to do this... (Setting the rotations etc)

 

Link to comment
  • Moderators
8 hours ago, ReZurrecti0n said:

. I'd much rather use rockets that either hit or miss.

 

Here some code snippets I ripped out of one of my scripts. The code was used to calculate the new projectile position based on frame time. This would terminate different projectile speeds based on FPS.

 

-- add function findRotation
local findRotation = function ( x1, y1, x2, y2 )
    local t = -math.deg( math.atan2( x2 - x1, y2 - y1 ) )
    return t < 0 and t + 360 or t
end
-- add function findPitch

local findPitch = function (camerax,cameray,cameraz,pointx,pointy,pointz)

	local dX=camerax-pointx
	local dY=cameraz-pointz
	local dZ=cameray-pointy

	local pitch=math.atan2(dY,math.sqrt(math.pow(dZ,2) + math.pow(dX,2)));
	return pitch
end

 

local xr, yr, zr = getElementRotation(source, "ZXY") -- source is projectile

-- xr, yr, zr is saved inside of projectileData.rotation

 

local targetX, targetY, targetZ = getElementPosition(target) -- target is projectile
local rotZ = findRotation(newX, newY, targetX, targetY) + 180
local pitch = findPitch(newX, newY, newZ, targetX, targetY, targetZ)


local rotX = pitch*(180/math.pi)


local newRotX = projectileData.rotation.x
local newRotZ = projectileData.rotation.z

local rotationDistanceX = (projectileData.rotation.x - rotX + 360) % 360;
if (rotationDistanceX > 180) then
	rotationDistanceX = 360 - rotationDistanceX
	newRotX = newRotX + math.min(rotationDistanceX, behaviourData.rotationSpeed * speedMultiplier)
else

	newRotX = newRotX + -math.min(rotationDistanceX, behaviourData.rotationSpeed * speedMultiplier)
end


local rotationDistanceZ = (projectileData.rotation.z - rotZ + 360) % 360;
if (rotationDistanceZ > 180) then
	rotationDistanceZ = 360 - rotationDistanceZ
	newRotZ = newRotZ + math.min(rotationDistanceZ, behaviourData.rotationSpeed * speedMultiplier)
else
	newRotZ = newRotZ + -math.min(rotationDistanceZ, behaviourData.rotationSpeed * speedMultiplier)
end


projectileData.rotation.x = newRotX
projectileData.rotation.z = newRotZ


local rotationZ = -projectileData.rotation.z
if creatorVehicle then -- if the projectile creator was a vehicle, then add 180 to invert the rotation.
	rotationZ = rotationZ + 180
end

setElementRotation(element, projectileData.rotation.x, projectileData.rotation.y, rotationZ, "ZXY")

 

 

 

 

 

 

 

  • Thanks 1
Link to comment

I don't quite understand how the createProjectile function works when it comes to using those extra arguments with rotations and velocity:

local ped=createPed(200,-1665,-2185,34.5,0.0) -- Our Test Ped
local rocket=createProjectile(ped,19,-1665,-2185,34.5,0,nil,0,0,180.0,0,0,1.0) -- Our Test Rocket

I would expect this to ignore the default aim target and just create a rocket on the ped and then fire the projectile behind the ped in a straight line, similar to what it would default as if a vehicle was used as the creator instead. However, this fires the projectile to the right side of the ped (90.0) and also is launched very high into the air even. When I changed that last 1.0 argument to 0.1, the projectile would then fire to the left of ped and end up in the ground not very far from the ped. And all I did was change the velocity argument? This puzzles me...

The 'force' argument I don't think would have any effect on a rocket projectile, right? (Wiki example uses a rocket with force of 200 though) What are the valid values? 0.0 to 1.0 maybe?

What I think I'm doing wrong is setting the velocity speeds incorrectly therefore I'm not getting expected results. So, let's just say I want the rocket to fire straight forward from the ped just as it does by default for a vehicle. What arguments would I put into the function?

local rocket=createProjectile(ped,19,-1665,-2185,34.5,0,nil,0,0,0.0,0,0,1.0) -- ???

I guess I just don't understand velocity and how it could affect the direction of a projectile

  • Like 1
Link to comment

If you have OOP enabled, you can use the matrix forward vector multiplied by a scalar coefficient of the magnitude (i.e. strength of the velocity)

local magnitude = 0.5
local rocket = createProjectile(ped, 19, x, y, z, 1.0, nil, 0, 0, 0, ped.matrix.forward * magnitude)

Otherwise you can use

local m = getElementMatrix(ped)
local forward = Vector3(m[2][1], m[2][2], m[2][3]) -- offset from player position to position 1m ahead of them taking into account the rotation
local magnitude = 0.5
local rocket = createProjectile(ped, 19, x, y, z, 1.0, nil, 0, 0, 0, forward * magnitude)

Or, if you prevent to avoid using Vector3

local m = getElementMatrix(ped)
local forwardX, forwardY, forwardZ = m[2][1], m[2][2], m[2][3] -- offset from player position to position 1m ahead of them taking into account the rotation
local magnitude = 0.5
local rocket = createProjectile(ped, 19, x, y, z, 1.0, nil, 0, 0, 0, forwardX * magnitude, forwardY * magnitude, forwardZ * magnitude)

 

Edited by MrTasty
  • Thanks 1
Link to comment
  • Moderators

Note: you can also apply the matrix of the ped to the projectile. It might not have the correct rotation in the beginning, but you can correct that.

setElementMatrix

 

Edited by IIYAMA
  • Thanks 1
Link to comment

Maybe I'm getting in over my head here and need to slow down a bit as I still don't understand what Velocity does exactly, let alone jump into something deeper I have no understanding of such as matrixes, lol... It seems the rotation of the projectile doesn't affect the movement at all, yet the Velocity arguments do. In the end, I've just decided to go with the simple fix of using heat seekers and maybe one day come back to this problem and consult this thread. I'm sure the answers are here (Thanx IIYAMA, MrTasty), I just need to study up on this stuff...

createProjectile(ped,20,x,y,z,1.0,localPlayer,270.0,0.0,0.0,0.0,0.0,0.1)

This creates the rocket on the ped which first launches upwards a tiny bit, then changes direction and rotation towards the target. This way, the projectile doesn't end up in the ground of anything before it starts to seek out the target. Not the desired result of course, but this will still work. Just going to move on and start working on other pieces of my AI script :)

  • Like 1
Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...