godotengine / godot-docs

Godot Engine official documentation
https://docs.godotengine.org
Other
3.95k stars 3.22k forks source link

Clarification on Node3D.rotate() axis and workaround for global coordinates #9930

Open 3p0ch-NG opened 2 months ago

3p0ch-NG commented 2 months ago

Godot version: 4.3

With Node3D.rotate(axis, angle) it was unclear what coordinate system the axis Vector3D should be in. Since there's also a rotate_object_local() method, it looked like it would work using global coordinates for the axis, but when I tested it seems like it actually uses the parent node's Transform for the rotation axis. I suggest adding the following clarification and workaround if you want to rotate based on global coordinates:

This rotates the object using axis in the parent node's transform. If you instead want to rotate based on an axis using global coordinates, you can write the following method

func rotate_object_global(axis: Vector3, angle: float) -> void:
    rotate_object_local(to_local(global_position + axis), angle)

or if many objects will need to rotate using an axis defined with global coordinates you could add this method to an Autoload for the rotating nodes to call

func rotate_object_global(rotating_node: Node3D, axis: Vector3, angle: float) -> void:
    rotating_node.rotate_object_local(rotating_node.to_local(rotating_node.global_position + axis.normalized()), angle)

The specific use-case that I ran into was trying to program a turret that was a child of a moving CharacterBody3D to aim at an enemy, which would naturally be done using global coordinates, but the fact that the parent was moving led to very strange behavior until I realized that rotate() wasn't using global coordinates.

URL to the documentation page: https://docs.godotengine.org/en/stable/classes/class_node3d.html#class-node3d-method-rotate