How to make camera relative movement in RE/SH style Horrow

Godot 4.2

Hi all! I started learning how to game make with godot about 2/3 weeks ago, with very little experience (I made a few Flash games about 15 years ago) and I’m trying to come to terms with everything new.

I’m trying to make a survival horror, along the lines of original RE and Silent Hill, so fixed camera angles - however, I’ve reached an issue where my character will control fine, but if I cut to a camera angle that is facing the front of the character my brain obviously goes, I need to push up on the controller to go back through the door I entered, but in the game world, that’s actually back - and it’s causing a bit of a struggle for me to make that connection in my head.

So i’m trying to find out/figure out how to do camera relative movement, in a fixed angle camera setting and i’m having 0 luck, I can find loads for Unity, but none for Godot

I know I need to code my character to respond to whatever Camera3D is active, but I don’t know how to do that and I don’t know how to make my controls relative to that. If anyone can give me some help, I’d really appreciate it.

Please see my current code, below

extends CharacterBody3D


var SPEED = 3.0


var walking_speed = 3.0
var running_speed = 4.75

@onready var animation_player = $Visuals/mixamo_base/AnimationPlayer
@onready var visuals = $Visuals

var walking = false
var running = false



func _physics_process(delta: float) -> void:

if Input.is_action_pressed("sprint"):
SPEED = running_speed
running = true
animation_player.play("running")
else:
SPEED = walking_speed
running = false

if Input.is_action_just_released("sprint"):
animation_player.play("walking")



# Get the input direction and handle the movement/deceleration.
var input_dir := Input.get_vector("left", "right", "forward", "backwards")
var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
velocity.x = direction.x * SPEED
velocity.z = direction.z * SPEED

visuals. look_at(direction + position)

if !walking:
walking = true
animation_player.play("walking")


else:
velocity.x = move_toward(velocity.x, 0, SPEED)
velocity.z = move_toward(velocity.z, 0, SPEED)

if walking:
walking = false
animation_player.play("idle")




move_and_slide()

Hey you can try assigning an active camera variable at the top of your script:

@onready var active_camera : Camera3D = null  # Placeholder for the active camera

Then in the ready() function assign the active camera:

func _ready() -> void:
    # Initialize the active camera if it's not set
    if !active_camera:
        active_camera = get_viewport().get_camera_3d()  # Get the current active camera

Then use the Cameras basis position to adjust the movement:

# Get input direction from the player
    var input_dir := Input.get_vector("left", "right", "forward", "backwards")

    if input_dir != Vector3.ZERO:
        # Transform the input direction to be relative to the camera's orientation
        var camera_basis = active_camera.transform.basis

        # Flatten the camera basis to avoid vertical movement influence
        camera_basis.y = Vector3(0, 0, 0)

        # Apply the camera's rotation to the input direction
        var direction = (camera_basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()

        # Move the character based on the camera-relative direction
        velocity.x = direction.x * SPEED
        velocity.z = direction.z * SPEED

I haven’t tested this, but hoping this will push you in the right direction. Good luck!

Thank you!

When I get a chance this week I shall try and apply this - appreciate it greatly

I gave this a try last night and kept running into errors, I think part of it is because I don’t have a string set up for my 3D camera

I did find another way around it, but then ran into issues of my character moving the correct way but also rotating through the level.

I think i’m going to go with tank controls - but give things like a sprint option and maybe a dodge/back step mechanic to give the player a bit more fluid movement