Shooting in 3D, vector math problem

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By sxkod

Hi all

I am stuck with projectile math! I have a player in FPS setup with camera being the child of the player. On key press, I want to instance a bullet scene [a rigid body] just in front of camera and then apply_impulse to it to go in the direction camera is facing at the time of firing.

if Input.is_key_pressed(KEY_F):
	_proj()

func _proj():
	var proji=preload("res://bullet.tscn").instance()
	globals.world.add_child(proji)
	proji.set_owner(globals.world)
	proji.set_translation(firepoint.global_transform.origin)
	proji.apply_impulse(firepoint.global_transform.origin,Vector3(0,0,-20))

I have the above code. However the impulse seem to be going towards the global Z-20 rather than the camera / firepoint [a spatial child of camera] direction. I tried camera.global_transform as well and still the same results! I tried just the transform but still the same.

I meant

proji.apply_impulse(firepoint.transform.origin,firepoint.transform.origin*10)

proji.apply_impulse(firepoint.global_transform.origin,firepoint.transform.origin*10) 

  proji.apply_impulse(firepoint.global_transform.origin,firepoint.transform.origin*Vector3(0,0,-10))

What am I doing wrong?
I am obviously out of my depth!!
Thanks

:bust_in_silhouette: Reply From: wombatstampede

Hi sxkod,
I put up a general info about local/global transforms and some common calculations here:
https://godotdevelopers.org/forum/discussion/18480/godot-3d-vector-physics-cheat-sheet

To your problem:

Positioning the bullet:
You’re setting the local translation/origin of the bullet with the global origin of the firepoint. This might work if the bullet is child a parent which has the position (0,0,0).
It is safer to set either

proji.set_global_transform(firepoint.global_transform)

…to set projis position and rotation equal to firepoint) or…

proji.global_transform.origin=firepoint.global_transform.origin

…to just set projis position equal to firepoint. (but not rotation)

If you would want to offset the bullit i.e. 0.5m along the firepoints z-axis then you could use:

proji.global_transform.origin += firepoint.global_transform.basis.z * 0.5

or

proji.global_transform.origin += firepoint.global_transform.basis.z * -0.5

… for the other direction.

Be the force with you:
apply_impulse receives two parameters:
-1: An offset in global coordinate space to the rigidbodies origin. So in this case this would probably simply be (0,0,0), or you could use apply_central_impulse() as well.
-2: Is the force/impulse vector in the global coordinates space (so rotation is global).

So applying the impulse would be:

const MY_FORCE = 100

proji.apply_central_impulse(firepoint.global_transform.basis.z * MY_FORCE * -1)

This applies a force of “100” to the bullit (you may use more or less depending on the mass you set on the bullet and how far and fast you want it to go) in the direction of -z of the firepoint. Should the bullet go “backwards” then remove the * -1 of the line above.

Hi wombatstampede,

That worked. I also read your write up. For someone mathematically challenged as me, that is a clear explanation. So, thanks so much.

sxkod | 2019-02-16 13:46

Glad that it worked. Thank you for answering.

wombatstampede | 2019-02-16 15:30

1 Like