master branch build commit 51991e20143a39e9ef0107163eaf283ca0a761ea
Also tried in the 4.2 branch
Question
I am trying to fire a rigid body projectile using
var inst = bullet.instantiate()
inst.global_transform = camera.global_transform
inst.global_transform.origin += camera.global_transform.basis.z * 2 #to move the projectile outside of the player collision sphere (2 is probably too high)
inst.apply_central_impulse(camera.transform.basis.z * 50)
#get_tree().get_root().add_child(inst)
add_child(inst)
using get_tree().get_root().add_child(inst) has the projectile firing from 0,0,0 at odd angles depending on camera orientation. (aiming up sends it down, aiming down sends it up).
Using add_child(), which seems wrong, spawms the projectile near the player and fires it but still does not go where i am aiming.
To summarize their approach (which I’ve also used and works great in my opinion):
You want to use your camera to create a raycast, which in turn gets you a destination point (either at the end of the raycast or the point it collides with an object).
Then you use that destination point and your projectile spawn point to create a directional vector, in pseudocode something like: direction_vector = destination_point - projectile_spawn_point).normalized()
which you can then apply to your projectile to shoot it: projectile.set_linear_velocity(direction_vector * projectile_velocity)
(I use set_linear_velocity instead of apply_central_impulse )
I got it working by using a similar concept to what you described:
var inst = bullet.instantiate()
get_tree().get_root().add_child(inst)
var start = camera.project_ray_origin(get_viewport().get_size()/2)
var end = start + camera.project_ray_normal(get_viewport().get_size()/2) * 2
var direction = (end - camera.global_transform.origin).normalized()
inst.global_transform.origin = end #use the end of the rsycast for the muzzle offset/projectile start location
inst.apply_central_impulse(direction * 50)
This seems to fire a projectile perfectly. Although if the velocity is high it seems to miss collisions even with CCD and with physics ticks at 240
negative global_transform.basis.z was what i needed. also did not need to set
inst.global_transform = camera.global_transform
Both the raycast way and this way have the same final result although id assume the math on the transforms is cheaper then raycasting from a 2d point in the viewport. Not sure though.