How do I rotate a 3d object around its local axis with absolute angle value?

Attention Topic was automatically imported from the old Question2Answer platform.

I have a sword with local x, y and z axes. (blade of sword is local y, right half of handle is local x):

When running my game, the sword blade is facing up, and I need the sword to rotate against its local z axis based on the “ui_left”, “ui_right”, “ui_down” and “ui_up” vector, like so: I can use `rotate_object_local(Vector3.BACK, radians)` to rotate it about the local z axis, but the angle provided needs to be a relative value, whereas the direction I get from `direction.angle()` is absolute. How do I rotate the sword around its local axis when I have an absolute angle value?

Node3D’s `rotation()` and `rotation_degree()` methods allow you to rotate your sword by an absolute value.

Example:

``````func _process(delta: float) -> void:
if Input.is_action_just_pressed("ui_left"):
\$Sword.rotation_degrees.z = 170
if Input.is_action_just_pressed("ui_right"):
\$Sword.rotation_degrees.z = 10
if Input.is_action_just_pressed("ui_up"):
\$Sword.rotation_degrees.z = 70
if Input.is_action_just_pressed("ui_down"):
\$Sword.rotation_degrees.z = -70
``````

I need the sword to rotate around its local axis, not the global axis.
For example, here’s what the sword rotating around the y axis looks like:
` -|-------`

` -|--`

` +`

` ---|-`

` -------|-`

It works up until the point when I move or transform the sword somewhere else.
This is what that looks like:

``````    /
/
/
-/<

|
|
|
-+<
|

\
\
\
-\<
``````

What I want however, is the sword rotating around it’s local axis, just like I can use `transform.basis` to get the local x, y and z directions.

``````        /
/
/
-/<

/
/
-+<

<
-+<

-+<--

-+<
>

-+<
\
\

-+<
/
/
/
``````

al1f | 2023-06-18 23:39

you can make your sword node the child of another node3d called Pivot in this case. This node is used to move the weapon in global space, while the sword node is moved in its local space with rotation().

``````Pivot
|
-> Sword
``````

Example:

``````func _process(delta: float) -> void:
if Input.is_action_just_pressed("ui_left"):
\$Pivot/Sword.rotation_degrees.z = 170
``````

ld2studio | 2023-06-19 05:26

It’s a bit unintuitive but it works. I still run into issues with rotation sometimes though.

al1f | 2023-06-20 09:14