Search code examples
transformgodot4

Godot : move a child node according to parent coordinate system


Firstly, I read everything I could about transform and matrices operations on them, but still, I cannot comprehend how to work with them.

I have a player character with a camera as a child node of two pivots, as the image below player node and camera setup

This camera can turn in y axis and x axis thru code.

I wish to spawn a bullet object, rigidBody3D thru code if I do a left-click, move it in front of the camera with a distance of let's say 1m. So along its Z axis, which could be pointing up or down depending on the camera angle.

Then apply an impulse, along the same axis.

Here is the code spawning the bullet (within player script):

func _unhandled_input(event: InputEvent):
    if event is InputEventMouseMotion:
        if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
            twist_input = - event.relative.x * mouse_sensitivity
            pitch_input = - event.relative.y * mouse_sensitivity
    if event is InputEventMouseButton:
        if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
            var bullet = load("res://bullet.tscn")
            var Bullet = bullet.instantiate()
            $"Twist Pivot/Twitch Pivot/Camera3D".add_child(Bullet)
            Bullet.position = $"Twist Pivot/Twitch Pivot/Camera3D".global_position

Here is the code within bullet script: bullet script

However when I launch the game and left-click, the bullet stays in the air, seems to be above me and not directly in front of me, and does not move: gamewindow

Please explain to me what I am doing wrong, also if you know any good tutorial or doc that may be more easy to understand than the one from godot, as I seem to not be able to grasp its concept, I would greatly appreciate it...


Solution

  • So after many experimentation and math :

    yes, it seems that having a rigidbody child of character body deactivate physics, not sure why but meh, so i have to make it child of my level node (node3D)

    i wasn't using the good transform matrices, also learnt you can use global_transform to get your local vector on global system coordinates, wich gives the code :

    if event is InputEventMouseButton:
        if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
            var bullet = load("res://bullet.tscn")
            var Bullet = bullet.instantiate()
            get_parent().add_child(Bullet)
            print($"Twist Pivot/Twitch Pivot/Camera3D".global_transform.basis)
            Bullet.position = $"Twist Pivot/Twitch Pivot/Camera3D".global_position + $"Twist Pivot/Twitch Pivot/Camera3D".global_transform.basis * Vector3(0,0,-1) 
    

    then in bullet code :

    func _ready():
    #pass
    var camera = get_node("/root/World/player/Twist Pivot/Twitch Pivot/Camera3D")
    apply_central_impulse(-camera.global_transform.basis.z * 5)
    

    My mistakes where mostly not referencing good nodes