#Help with Camera/Character Directions

13 messages · Page 1 of 1 (latest)

unborn hazel
#
extends CharacterBody3D

@onready var spring_arm_3d = $SpringArm3D
@onready var camera_3d = $SpringArm3D/Camera3D

var capture_movement_vector = Vector3.ZERO

enum Direction {
    NORTH,
    NORTHEAST,
    EAST,
    SOUTHEAST,
    SOUTH,
    SOUTHWEST,
    WEST,
    NORTHWEST
}

var direction_vectors = {
    Direction.NORTH: Vector3(0, 0, -1),
    Direction.NORTHEAST: Vector3(1, 0, -1).normalized(),
    Direction.EAST: Vector3(1, 0, 0),
    Direction.SOUTHEAST: Vector3(1, 0, 1).normalized(),
    Direction.SOUTH: Vector3(0, 0, 1),
    Direction.SOUTHWEST: Vector3(-1, 0, 1).normalized(),
    Direction.WEST: Vector3(-1, 0, 0),
    Direction.NORTHWEST: Vector3(-1, 0, -1).normalized()
}

const SPEED = 2.0
const JUMP_VELOCITY = 4.5

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")


var direction: Direction

var direction_names = [
    "north",
    "northeast",
    "east",
    "southeast",
    "south",
    "southwest",
    "west",
    "northwest"
]```
#
@onready var animated_sprite: AnimatedSprite3D = $AnimatedSprite3D

func get_direction_from_vector(movement_vector: Vector3) -> Direction:
    var best_direction = Direction.NORTH
    var max_dot = -1.0

    for dir in direction_vectors.keys():
        var dot = movement_vector.dot(direction_vectors[dir])
        if dot > max_dot:
            max_dot = dot
            best_direction = dir
    #print(best_direction)
    return best_direction
    
func get_direction_from_angle(angle: float) -> Direction:
    #print(angle)
    if angle >= 337.5 or angle < 22.5:
        return Direction.NORTH
    elif angle >= 22.5 and angle < 67.5:
        return Direction.NORTHEAST
    elif angle >= 67.5 and angle < 112.5:
        return Direction.EAST
    elif angle >= 112.5 and angle < 157.5:
        return Direction.SOUTHEAST
    elif angle >= 157.5 and angle < 202.5:
        return Direction.SOUTH
    elif angle >= 202.5 and angle < 247.5:
        return Direction.SOUTHWEST
    elif angle >= 247.5 and angle < 292.5:
        return Direction.WEST
    else:
        return Direction.NORTHWEST
        
func get_direction_from_vector(movement_vector: Vector3) -> Direction:
    var angle = rad_to_deg(atan2(movement_vector.x, -movement_vector.z))
    if angle < 0:
        angle += 360

    return get_direction_from_angle(angle)```
#
func _physics_process(delta):
    if not is_on_floor():
        velocity.y -= gravity * delta

    if Input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    var movement_vector = Vector3.ZERO
    if Input.is_action_pressed("move_up"):
        movement_vector.z -= 1
    if Input.is_action_pressed("move_down"):
        movement_vector.z += 1
    if Input.is_action_pressed("move_left"):
        movement_vector.x -= 1
    if Input.is_action_pressed("move_right"):
        movement_vector.x += 1

    if movement_vector != Vector3.ZERO:
        movement_vector = movement_vector.normalized()
        last_movement_vector = movement_vector
        var direction_camera = (camera_3d.transform.basis * Vector3(movement_vector.x, 0, movement_vector.z)).normalized()
        direction = get_direction_from_vector(direction_camera)
        animated_sprite.play("run_" + direction_names[direction])
    else:
        var direction_camera = (spring_arm_3d.transform.basis * Vector3(last_movement_vector.x, 0, last_movement_vector.z)).normalized()
        direction = get_direction_from_vector(direction_camera)
        animated_sprite.play("idle_" + direction_names[direction])

    var direction_camera_velocity = (spring_arm_3d.transform.basis * Vector3(movement_vector.x, 0, movement_vector.z)).normalized()
    velocity.x = direction_camera_velocity.x * SPEED
    velocity.z = direction_camera_velocity.z * SPEED

    move_and_slide()```
unborn hazel
fluid marsh
#

You're only using the orientation of the camera to choose the displayed orientation of your sprite.
Should you not also use the orientation of your character ?
I would think what you want is the orientation of your character relative to the camera

#

Something like direction = camera.quaternion.inverse() * <your character's forward vector, I did't really get where to find it in your code>

unborn hazel
#

Wouldn't my forward vector be my last movement vector

fluid marsh
#

If your character is represented by something that inherits Node3D, I think their forward direction is supposed to be given by character.quaternion * Vector3.FORWARD ?

unborn hazel
#

I have been going at this all day again @fluid marsh , still can't figure out how to get it to work

fluid marsh
fluid marsh
#

wait, usually people have 3d models and they orient their model in the direction of motion, setting their forward vector, but youi didn't need to so maybe you didn't do it

#

what you'd need to do is use the look_at function if your movement vector is nonzero