I eventually got it working using that method using the second and third parameters that you mentioned, but I opted a different approach with similar results. Based on this post here(credit). With some tweaking, it’s moving in all the proper directions, and feels great so far; and no weird crashes when I change the basis anymore.
The issue now is that it’s falling apart at the mesh level with how I’m rotating it since I chose to rotate the mesh like this:
if Input.is_action_pressed("movement"):
var dir = Input.get_vector("move_backward", "move_forward", "move_right", "move_left").normalized()
dir = dir.rotated(player_camera.yaw_node.rotation.y)
var target_rotation = atan2(dir.y, dir.x) - rotation.y
mesh.rotation.y = lerp_angle(mesh.rotation.y, target_rotation, turn_speed * delta)
translate(Vector3(-dir.y, 0, -dir.x) * move_speed * delta)
Video
Current Code So Far:
extends CharacterBody3D
@export var move_speed = 5.0
@export var jump_height = 5.0
@export var turn_speed = 5.0
@onready var wall_change_detection: RayCast3D = %WallChangeDetection
@onready var player_camera: PlayerCamera = $PlayerCamera
@onready var mesh: MeshInstance3D = $Mesh
var transitioning : bool = false
func _input(event: InputEvent) -> void:
if event.is_action_pressed("interact") and not transitioning:
if wall_change_detection.is_colliding():
align_to_new_normal(wall_change_detection.get_collision_normal(), wall_change_detection.get_collision_point())
func _physics_process(delta: float) -> void:
### Add the gravity.
#if upright:
#velocity.y += -5 * delta
if Input.is_action_pressed("movement"):
var dir = Input.get_vector("move_backward", "move_forward", "move_right", "move_left").normalized()
dir = dir.rotated(player_camera.yaw_node.rotation.y)
var target_rotation = atan2(dir.y, dir.x) - rotation.y
mesh.rotation.y = lerp_angle(mesh.rotation.y, target_rotation, turn_speed * delta)
translate(Vector3(-dir.y, 0, -dir.x) * move_speed * delta)
move_and_slide()
func align_to_new_normal(new_normal:Vector3, attach_point:Vector3):
transitioning = true
var original = self.transform.basis.y
var cosa = original.dot(new_normal)
var alpha = acos(cosa)
var axis = original.cross(new_normal)
axis = axis.normalized()
var t = get_tree().create_tween()
t.tween_property(self, "transform", self.transform.rotated(axis, alpha), 0.2)
t.parallel().tween_property(self, "global_position", wall_change_detection.get_collision_point(), 0.2)
t.tween_callback(func(): transitioning = false)