Godot Version
4.5.1
Question
Hi y’all, I’m new to gd script and godot in general and I’m having some issues with 3D rotation. I took a little video and linked it below for reference. I also included the full script that I’m working with.
What I’m trying to accomplish is basically just rotating a cube as you would expect it to if you were to push against the top edge on any given side, as well as translating the cube a single unit(in this case 2m) in the same time frame.
I started by putting together some enums in order to easily map inputs for the rotate and move function.
On ready I set the basis to the identity basis, and during _physics process I’m handling the input. The if statement boils down to when you press a key rotate and move the appropriate direction.
A couple things are happening that I don’t quite understand.
- Why isn’t the
if not is_turning:check properly preventing multiple inputs from being registered at once? - I know that repeated transformations can cause the basis to deform and for the angles to get out of sync, but I thought that with orthonormalization and resetting the basis to the identity basis that this could be avoided? Is there something that I’m doing incorrectly?
There is obviously something that I’m missing here any help to identify what that is would be appreciated.
Video
Full Script
extends CharacterBody3D
enum axes {X,Z}
enum directions {FORWARD,BACK,LEFT,RIGHT}
var duration = 0.5
var rot_axis
var rot_dir
var move_axis
var move_dir
var is_turning
func _ready() -> void:
transform.basis = Basis.IDENTITY
func _physics_process(delta: float) -> void:
if not is_turning:
if Input.is_action_just_pressed("rotate_n"):
rot_axis = axes.X
move_axis =axes.Z
rot_dir = directions.BACK
move_dir = directions.FORWARD
rotate_and_move(rot_axis, move_axis,rot_dir,move_dir)
if Input.is_action_just_pressed("rotate_s"):
rot_axis = axes.X
move_axis = axes.Z
rot_dir = directions.FORWARD
move_dir =directions.BACK
rotate_and_move(rot_axis, move_axis,rot_dir,move_dir)
if Input.is_action_just_pressed("rotate_e"):
rot_axis = axes.Z
move_axis =axes.X
rot_dir = directions.FORWARD
move_dir = directions.FORWARD
rotate_and_move(rot_axis, move_axis,rot_dir,move_dir)
if Input.is_action_just_pressed("rotate_w"):
rot_axis = axes.Z
move_axis =axes.X
rot_dir = directions.BACK
move_dir = directions.BACK
rotate_and_move(rot_axis, move_axis,rot_dir,move_dir)
func rotate_and_move(rota_axis, mov_axis, rota_dir, mov_dir):
is_turning =true
print("Is Turning: ", is_turning)
$Pivot/Cube.basis = Basis()
$Pivot.basis = Basis()
var rot_axis_map = {0:{0:Vector3.FORWARD, 1:Vector3.BACK}, 1:{0:Vector3.LEFT, 1:Vector3.RIGHT}}
var move_axis_map = {0:{0:Vector3.FORWARD, 1:Vector3.BACK}, 1:{0:Vector3.LEFT, 1:Vector3.RIGHT}}
var tween = get_tree().create_tween()
tween.set_parallel(true)
tween.tween_property($Pivot/Cube, "transform", $Pivot/Cube.transform.rotated_local(rot_axis_map[rota_axis][rota_dir], deg_to_rad(90)), duration)
tween.tween_property($Pivot, "transform", $Pivot.transform.translated(move_axis_map[mov_axis][mov_dir]*2),duration)
await get_tree().create_timer(duration).timeout
is_turning =false
print("Is Turning: ", is_turning)
move_axis = axes.Z
rot_dir = directions.FORWARD
move_dir =directions.BACK
rotate_and_move(rot_axis, move_axis,rot_dir,move_dir)
elif Input.is_action_pressed("rotate_e"):
is_turning = true
rot_axis = axes.Z
move_axis =axes.X
rot_dir = directions.FORWARD
move_dir = directions.FORWARD
rotate_and_move(rot_axis, move_axis,rot_dir,move_dir)
elif Input.is_action_pressed("rotate_w"):
is_turning = true
rot_axis = axes.Z
move_axis =axes.X
rot_dir = directions.BACK
move_dir = directions.BACK
rotate_and_move(rot_axis, move_axis,rot_dir,move_dir)
func rotate_and_move(rot_axis, move_axis, rot_dir, mov_dir):
$Pivot.basis = Basis()
self.basis = Basis()
var rot_axis_map = {0:{0:Vector3.FORWARD, 1:Vector3.BACK}, 1:{0:Vector3.LEFT, 1:Vector3.RIGHT}}
var move_axis_map = {0:{0:Vector3.FORWARD, 1:Vector3.BACK}, 1:{0:Vector3.LEFT, 1:Vector3.RIGHT}}
var tween = get_tree().create_tween()
tween.set_parallel(true)
tween.tween_property($Pivot, "transform", $Pivot.transform.rotated_local(rot_axis_map[rot_axis][rot_dir], PI/2), 0.5)
tween.tween_property(self, "transform", self.transform.translated(move_axis_map[move_axis][move_dir]*2),0.5)
$Pivot.transform.orthonormalized()
self.transform.orthonormalized()