Note: Before following this tip/trick add these input map actions or similar:
“move_left”, “move_right”, “move_forward”, “move_backward”
The default CharacterBody3D template script suggests:
“you should replace UI actions with custom gameplay actions.”
Sometimes you just don’t want to replace existing actions.
So my current poor solution is declaring input_dir
as @export
variable and introducing and exporting custom_input_dir
.
@export var input_dir : Vector2
@export var custom_input_dir = false
and then introducing if not custom_input_dir:
statement:
Now it’s all ready.
This way you could now nest a subnode (with an attached script) under CharacterBody3D and override input_dir
, and that’s what we will talk about next.
Overriding input_dir
using subnode
Foreshadowing results:
How to:
class_name CharacterInput
extends Node
func _process(delta: float) -> void:
get_parent().input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
get_parent().custom_input_dir = true
Save this script as MyCharacterInput.gd
script and then use/add new node called CharacterInput: look up for node named CharacterInput, it should appear among other nodes, just use search.
Demo
Again, Final version
Full modified CharacterBody3D.gd
template script with ability to override input_dir
extends CharacterBody3D
const SPEED = 5.0
const JUMP_VELOCITY = 4.5
@export var input_dir : Vector2
@export var custom_input_dir = false
func _physics_process(delta: float) -> void:
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
# Handle jump.
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
if not custom_input_dir:
input_dir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
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()