4.4.1 I’m a complete beginner and I’ve been stuck on this for a very long time. Please help me. Part of me thinks it’s because my character isn’t facing the direction it’s moving. I’ve tried to fix this, but there are still bugs. This is the best version of my code so far.
extends CharacterBody3D
@export var camera:Camera3D
@onready var animation_tree = $AnimationTree
const SPEED = 5.0
const JUMP_VELOCITY = 4.5
var acceleration := 25.0
var angular_acceleration := 7
func _process(_delta: float) -> void:
if camera == null:
return
var to_camera = (camera.global_transform.origin - global_transform.origin).normalized()
var fwd := global_transform.basis.z
var left := global_transform.basis.x
var dot_fwd = fwd.dot(to_camera)
var dot_left = left.dot(to_camera)
var angle = rad_to_deg(atan2(dot_left, dot_fwd))
if angle < 0:
angle += 360
var snapped = int(round(angle / 45.0)) * 45 % 360
var dir_vector = Vector2.RIGHT.rotated(deg_to_rad(snapped)).normalized()
update_animation_parameters(dir_vector)
func _physics_process(delta: float) -> void:
## --- GRAVITY --- ###
if not is_on_floor():
velocity += get_gravity() * delta
# Handle jump.
#if Input.is_action_just_pressed("jump") and is_on_floor():
#velocity.y = JUMP_VELOCITY
## --- MOVEMENT --- ##
var input_dir := Input.get_vector("move_left", "move_right", "move_up", "move_down")
var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
direction = direction.rotated(Vector3.UP, camera.global_rotation.y)
if direction:
if is_on_floor() and velocity.y <= 0:
velocity.x = direction.x * SPEED
velocity.z = direction.z * SPEED
set_moving(true)
else:
velocity.x = move_toward(velocity.x, 0, delta * acceleration)
velocity.z = move_toward(velocity.z, 0, delta * acceleration)
set_moving(false)
move_and_slide()
func set_moving(value):
animation_tree["parameters/conditions/is_walking"] = value
animation_tree["parameters/conditions/idle"] = not value
func update_animation_parameters(input_dir:Vector2):
if input_dir == Vector2.ZERO:
return
animation_tree.set("parameters/idle/blend_position", input_dir)
animation_tree.set("parameters/run/blend_position", input_dir)
I can’t upload the video, so I’ll just share the link instead. VIDEO
Is the character a child of the camera? This would cause them to rotate with it and therefore move in the direction it’s facing. I don’t see how the character is rotated directly by code though so I might be misunderstanding the question. In that case, could you explain in more detail what is the desired result?
In my video, the character doesn’t face the correct direction, but the idle animation is displaying correctly. I just want the character to face the direction of the key I’m pressing. Do you understand what I mean?
To turn the character in the direction you’re pressing, I would get the y-rotation of the camera and set the character’s rotation to something relative to that, e.g.
Shouldn’t you be using the SpringArmPivot rotation here instead of the camera ? because the camera is a child of the springarm pivot and it doesn’t seems like it’s rotation.y is changing
The square box in front is the character’s forward direction, and the movement is relative to the camera angle like in a typical 3rd person controller. I tried to make it rotate before, but I kept running into weird issues. Can you help me out?
Alright guys, I figured it out — it was my mistake. When I rotated the root node, it made everything rotate with it. So I tried rotating just the sprite instead, and it worked!
var fwd : Vector3 = animated_sprite.global_transform.basis.z
var left : Vector3 = animated_sprite.global_transform.basis.x
var look_position := global_position + Vector3(velocity.x, 0, velocity.z)
animated_sprite.look_at(look_position, Vec