How best would I create a rig that allows character movement and collision detection while also having a top down style camera that follows the player, allowing the player to rotate independently of the camera orientation? Also, Node3D doesn't have a function called "move_and_collide()", so is there a better node I should be using in it's place? The following is the code I am currently using.

extends Node3D

var rotationSpeed: float = 1.35
var rotationInput: int = 0
var movementSpeed: int = 5
var inputVector: Vector2 = Vector2()
var movementVector: Vector3 = Vector3()

func _ready() -> void:
	pass

func _process(delta: float) -> void:
	# Handle Movement
	movementVector.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
	movementVector.z = Input.get_action_strength("move_backward") - Input.get_action_strength("move_forward")
	movementVector = movementVector.normalized() * delta * movementSpeed
	translate(movementVector)
	# Handle Rotation
	rotationInput = Input.get_action_strength("rotate_right") - Input.get_action_strength("rotate_left")
	rotate_y(delta * rotationSpeed * rotationInput)
  • Lousifr The function name is set_as_top_level not set_as_toplevel. You can also just assign a value to node's top_level property.

You probably want to use a character3d node. The camera, you set an offset from the player in process and have it lookat the player. generally, you add a focal point for the camera that is about at the character's neck. A 3d node or whatever parented to the character.

I think the easiest way to do this is make a 'SrpingArm' camera and attach it to a node that is always relative to player position, then rotate the SpringArm camera, rather than rotating the 'player' camera attached to the CharacterBody3D.

I found this demo helpful for my third-person mode, especially player/player.gd
Sounds like you want a birds-eye 'isometric' view but this is pretty similar.
Either way it's more complicated than first-person, so take your time to understand the geometry.

https://github.com/godotengine/tps-demo


This video does exactly what I want, but it's written for Godot 3, not Godot 4. The following is the code I've written so far, but I'm having trouble updating the code to GDScript 4.

Click to reveal Click to hide
extends CharacterBody3D

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

@export var speed = 10.0
@export var camera_rotation = 25

@onready var camera = $CameraRig/Camera
@onready var camera_rig = $CameraRig
@onready var cursor = $Cursor

func _ready():
	pass

func _physics_process(delta):
	# Handle gravity.
	if not is_on_floor():
		velocity.y -= gravity * delta

	# Get the input direction and handle the movement/deceleration.
	var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
	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
	else:
		velocity.x = move_toward(velocity.x, 0, speed)
		velocity.z = move_toward(velocity.z, 0, speed)

	move_and_slide()

In the _ready function, I'm supposed to use the function "set_as_toplevel(true)" on the camera rig and the cursor, but this function doesn't exist in Godot 4. What do I use in its place?

  • xyz replied to this.

    Lousifr The function name is set_as_top_level not set_as_toplevel. You can also just assign a value to node's top_level property.