Godot Version
4.4
Question
I’m using an orthographic projection, camera angled -30 down. Unfortunately, horizontal (left/right) movement appears to be faster than vertical (up/down) due to the projection. How can I fix this so it all appears to be the same in screen space? I tried with multipliers etc, but this skews the diagonal movement.
extends CharacterBody3D
@export var move_speed := 6.0
@export var move_speed2 := 8.0
@export var rotation_speed := 8.6
@export var gravity := 0.0
@export var deceleration := 36.0
@onready var anim = $player/AnimationPlayer
@onready var anim2 = $"../NPCs/player2/AnimationPlayer"
@onready var anim3 = $"../player3/AnimationPlayer"
@onready var anim4 = $"../player4/AnimationPlayer"
# our “north star” yaw for the box
var desired_yaw: float
func _ready():
# start off facing however the box is rotated in the editor
desired_yaw = $Box4.rotation.y
func _input(event):
# only catch key-presses for our movement actions
if event is InputEventKey and event.pressed:
for action in ["move_left","move_right","move_down","move_up"]:
if event.is_action(action):
_update_desired_yaw()
break
func _ground_axes_from_camera(cam: Camera3D) -> Array[Vector3]:
var right: Vector3 = cam.global_transform.basis.x
var up: Vector3 = cam.global_transform.basis.y
right.y = 0.0
up.y = 0.0
if right.length() > 0.0:
right = right.normalized()
if up.length() > 0.0:
up = up.normalized()
return [right, up] # [screen-right on ground, screen-up on ground]
func _update_desired_yaw() -> void:
var iv: Vector2 = Input.get_vector("move_left","move_right","move_down","move_up")
if iv == Vector2.ZERO:
return
var cam: Camera3D = $"../../SubViewport/CameraRig/Camera3D"
var axes: Array[Vector3] = _ground_axes_from_camera(cam)
var right: Vector3 = axes[0]
var up: Vector3 = axes[1]
# screen up is negative Y on the input vector
var raw: Vector3 = right * iv.x + up * -iv.y
var d: Vector3 = raw.normalized()
desired_yaw = atan2(d.x, d.z)
func _process(delta: float) -> void:
var iv: Vector2 = Input.get_vector("move_left","move_right","move_down","move_up")
var cam: Camera3D = $"../../SubViewport/CameraRig/Camera3D"
var axes: Array[Vector3] = _ground_axes_from_camera(cam)
var right: Vector3 = axes[0]
var up: Vector3 = axes[1]
if iv != Vector2.ZERO:
var raw: Vector3 = right * iv.x + up * iv.y
var d: Vector3 = raw
# facing
desired_yaw = atan2(d.x, d.z)
# uniform speed (diag included)
velocity.x = d.x * move_speed
velocity.z = d.z * move_speed
else:
velocity.x = move_toward(velocity.x, 0.0, deceleration * delta)
velocity.z = move_toward(velocity.z, 0.0, deceleration * delta)
# rotate toward desired_yaw (unchanged)
var box := $player
var current: float = box.rotation.y
var diff: float = wrapf(desired_yaw - current, -PI, PI)
var step: float = rotation_speed * delta
if abs(diff) <= step:
box.rotation.y = desired_yaw
else:
box.rotation.y = lerp_angle(current, desired_yaw, step)
# gravity & movement
velocity.y -= gravity * delta
move_and_slide()