Spatial Coordinates are not used when using GlobalTransform?

Godot Version

v3.6.stable.mono.official [de2f0f147] (with c# support)

Question

Hello Everyone !
I’m learning Godot and still in the “following video tutorial” stage.
I’m currently trying to follow this one : https://www.youtube.com/watch?v=gicXqKda_Xw&list=PLpfOedZZax4zUTdFteFUC3iOP34mAfaZf&index=11

But I’m stuck at one point and I don’t understand something in Godot. And I really want to understand what I’m doing before going further.

I have a Player scene, in which I’ve got a Spatial named “Gun” which is the spawning location for my bullets.

And in my Player script I’ve got this code :

	public void Shoot()
	{
		Spatial bullet = (Spatial) bulletScene.Instance();
		bullet.SetTranslation(Vector3.One);
		bullet.GlobalTransform = Gun.GlobalTransform;
		GetTree().GetRoot().CallDeferred("add_child", bullet);
	}

The bullet is correctly spawned, but the location and direction of the bullet doesn’t use the Gun spatial location at all, and I don’t understand why. The bullet keeps spawning in front of my face, even if I move the Gun Spatial anywhere else.

Is there some sort of “cache” for the scene that I need to clear or something ? The code seems “ok” (and it’s what the youtuber is using) but the result is really not the same, and I’m lost).

I’ve check as much documentation as I could before bothering you, but I don’t know what to do anymore… Any help is welcome :pray:

Here is a screen of my Player Scene, with the Gun Spatial location :

And here is the full Player Script if needed :

using Godot;
using System;
using static Godot.GD;

public class player : KinematicBody
{
	float lookAngle = 90.0f;
	[Export]
	float mouseSentivity = 1.5f;
	[Export]
	float moveSpeed = 10.0f;
	
	float gravity = 20.0f;
	
	float jumpForce = 8.0f;
	
	Vector3 velocity = new Vector3();
	
	Vector2 mouseDelta = new Vector2();
	
	Camera camera;
	
	PackedScene bulletScene;
	Spatial Gun;
	
	public override void _Ready()
	{
		base._Ready();
		camera = GetNode("Camera") as Camera;
		Gun = GetNode("Camera/Gun") as Spatial;
		bulletScene = (PackedScene) ResourceLoader.Load("res://scenes/Bullet.tscn");
	}
	
	public override void _Input(InputEvent ev)
	{
		if(ev is InputEventMouseMotion eventMouse)
		{
			mouseDelta = eventMouse.Relative;
		}
	}
	
	public override void _Process(float delta)
	{
		camera.RotationDegrees -= new Vector3(Mathf.Rad2Deg(mouseDelta.y),0 ,0) * mouseSentivity * delta;
		camera.RotationDegrees = new Vector3(Mathf.Clamp(camera.RotationDegrees.x, -lookAngle, lookAngle), camera.RotationDegrees.y, camera.RotationDegrees.z);
		
		RotationDegrees -= new Vector3(0, Mathf.Rad2Deg(mouseDelta.x),0) * mouseSentivity * delta;
		
		mouseDelta = new Vector2();
		
		
		if(Input.IsActionJustPressed("shoot"))
		{
			Shoot();
		}
	}
	
	public override void _PhysicsProcess(float delta)
	{
		velocity.x = 0;
		velocity.z = 0;
		
		var direction = new Vector2();
		
		if(Input.IsActionPressed("forward"))
			direction.y -= 15;
		if(Input.IsActionPressed("back"))
			direction.y += 15;
		if(Input.IsActionPressed("left"))
			direction.x -= 15;
		if(Input.IsActionPressed("right"))
			direction.x += 15;
	
		direction = direction.Normalized();
		
		var forward = GlobalTransform.basis.z;
		var right = GlobalTransform.basis.x;
		
		velocity.z = (forward * direction.y + right * direction.x).z * moveSpeed;
		
		velocity.x = (forward * direction.y + right * direction.x).x * moveSpeed;
		
		velocity.y -= gravity * delta;
		
		velocity = MoveAndSlide(velocity, Vector3.Up);
		
		if(Input.IsActionPressed("jump") && IsOnFloor()) //&& = et
		{
			velocity.y = jumpForce;
		}
	}
	
	public void Shoot()
	{
		Spatial bullet = (Spatial) bulletScene.Instance();
		bullet.SetTranslation(Vector3.One);
		bullet.GlobalTransform = Gun.GlobalTransform;
		GetTree().GetRoot().CallDeferred("add_child", bullet);
	}
}

Is it allowed here to offer to pay to get some help ?

I’m fairly sure your problem is that you are trying to set the transform before you add it to the tree. Try setting it after it is already in the tree.

Thank you for taking the time to respond.

I tried :

public void Shoot()
{
	Spatial bullet = (Spatial) bulletScene.Instance();
	//bullet.SetTranslation(Vector3.One);
	GetTree().GetRoot().CallDeferred("add_child", bullet);
	bullet.GlobalTransform = Gun.GlobalTransform;
	
}

It doesn’t change anything sadly :

If I understand correctly the code :

First we are creating a Spatial “bullet” by instancing the BulletScene
Then we add it to the tree (at the root), using callDefered to be sure the scene is ready before we do the add_child
Then we apply the exact same transform / scale and anything to bullet from the Gun Spatial by copying the globalTransform from Gun to bullet.

Your AnimationPlayer is controlling the gun transform so as soon as you play or not edit your gun any more it snap to the Animationplayer default gun transform
If you want to manipulate your gun transform you can disable to gun transform in the AnimationPlayer

That’s was it, you are a genius, thank you so much for taking the time to help <3

1 Like