The bullet is moving with a gun after shoot Input

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Bishop
:warning: Old Version Published before Godot 3 was released.

Hello,
How to make the bullet independent from movement of gun barrel?
Thanks for help

this script I use for bullet moving…“gule” in the script is bullet

extends RigidBody

export (int) var gule_speed = 850

func _ready():
	set_process(true)
	set_fixed_process(true)

func _fixed_process(delta):
	var dir = get_global_transform().basis*Vector3(0,0,-1).normalized()
	if Input.is_action_pressed("shoot"):
		self.set_linear_velocity(Vector3(dir * gule_speed ))
		self.apply_impulse(Vector3(),dir * delta * gule_speed ) 


func _on_gule_area_body_enter( body ):
	queue_free()

https://youtu.be/U4zGecsOc6Y

Bishop | 2017-02-24 22:29

:bust_in_silhouette: Reply From: avencherus

The most likely source of this problem is that your bullets are being parented to the gun object. They will then by default inherit all the transformations of their parent.

Bullets should either be created and added directly to the root, or some category node that shares the same origin as your root node.

If you want to keep them parented, you will have to do some extra work to keep track of a global position for them, increment that value, and update their global origin according to that.

Yes…I got it! …get_node("/root").add_child(bullet)

Bishop | 2017-05-24 20:47

:bust_in_silhouette: Reply From: eons

If you have bullets as children of a Node2D gun, your bullets will get the gun and other parents transformations.

I prefer to have a bullet pool somewhere on the scene and get reference of it by searching groups, is more dynamic and scene-independent.

Another option is to add them to a Node child of the gun or make the gun a Node itself, Node does not have position or any transform information and bullets added there won’t be affected by any parent transform (not sure if this is a bug or intended but is useful).

:bust_in_silhouette: Reply From: Bishop

Thanks guys,
Yes I have spawner ( Position3D node) parented to the gun barrel
but I find solution…I set bullet toplevel

set_as_toplevel(true)

and this works great…now bullets are independent of the movements( transformations ) gun barrel after shoot input.
maybe it will help others

Yes, that’s a good option too.

avencherus | 2017-02-25 04:08

To be honest it’s not really a good option. Yes, it works for now, but it’s another back door added by someone who didn’t understand object orientation good enough.

By calling set_as_toplevel() you are removing ALL influences of parent nodes on the bullet. Let’s say you want to implement some kind of level switching animation, so when the player enters a door the whole screen should shrink and move away to the side (like the animations they use on TV for sports replays).
Thanks to the object oriented nature of Godot this is not much of a problem - the whole game is a scene and can be resized, moved, rotated etc.
Unfortunately your bullet won’t be affected by that since you disabled ALL influence of parent nodes.

That’s why it would be a better idea to just add the bullet as a child to the parent of the spawner.
If you need more control or just want an even cleaner solution you can add a signal that is emitted when a shot is fired that passes the new bullet as a parameter, so the scene that owns the spawner can decide which node should be the parent of the new bullet.

The example with the replay cam may not work very well in this case, but being able to spontaneously turn a scene into a subscene of a new larger scene is probably the biggest feature of Godot which enables you to come up with designs that would be a lot more awkward to build in other engines, so by training to build everything in a reuseable way it will become easier to be creative with the engine later.

Warlaan | 2017-02-25 10:15

func shoot():
	var bullet = preload("res://objects/test_bullet_01.tscn").instance()
	bullet.set_transform(get_node("gun_barrel/bullet_spawn").get_global_transform().orthonormalized())
	get_parent().add_child(bullet)
	bullet.set_linear_velocity(get_node("gun_barrel/bullet_spawn").get_global_transform().basis[2].normalized()*bullet_speed)

This is probably a better solution and works but bullet is spawning on the center of a
gun_barrel not from the bullet_spawn node.

Bishop | 2017-02-25 20:43