Need help fixing stepping system

Godot Version

Godot 4.6 Stable

Question

I tried to make a custom 3d player system, and it worked for the most part, till I added the stepping part, I tried a lot to try and make it work but it refuses to, I’m still somewhat new to Godot (I started at 4.5) so I need help if anyone can help.

extends CharacterBody3D

@export var speed := 5.0
@export var sprint_speed := 8.5
@export var mouse_sens := 0.002

@export var max_stamina := 100.0
@export var sprint_drain := 25.0
@export var stamina_regen := 18.0
@export var min_stamina_to_sprint := 5.0

var stamina := max_stamina
var is_sprinting := false

@export var interact_distance := 3.0

@onready var camera: Camera3D = $Camera3D
@onready var prompt: Label = $CanvasLayer/InteractionPrompt

var gravity: float = ProjectSettings.get_setting(“physics/3d/default_gravity”)
var pitch := 0.0

func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
floor_snap_length = 0.5

func _unhandled_input(event):
if event is InputEventMouseMotion:
rotate_y(-event.relative.x * mouse_sens)

	pitch = clamp(pitch - event.relative.y * mouse_sens,
		deg_to_rad(-89), deg_to_rad(89))
	camera.rotation.x = pitch

func _physics_process(delta):
_handle_movement()
_handle_stamina(delta)
_handle_gravity(delta)

move_and_slide()

_update_interaction_ui()

func _input(event):
if event.is_action_pressed(“interact”):
_try_interact()

func _handle_movement():
var input_dir = Input.get_vector(“move_left”, “move_right”, “move_forward”, “move_back”)
var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()

is_sprinting = Input.is_action_pressed("sprint") and stamina > min_stamina_to_sprint
var current_speed = sprint_speed if is_sprinting else speed

velocity.x = direction.x * current_speed
velocity.z = direction.z * current_speed

func _handle_stamina(delta):
if is_sprinting:
stamina -= sprint_drain * delta
else:
stamina += stamina_regen * delta

stamina = clamp(stamina, 0.0, max_stamina)

func _handle_gravity(delta):
if not is_on_floor():
velocity.y -= gravity * delta
else:
velocity.y = -0.1

func _get_interactable():
var space_state = get_world_3d().direct_space_state

var from = camera.global_position
var to = from + (-camera.global_transform.basis.z * interact_distance)

var query = PhysicsRayQueryParameters3D.create(from, to)
query.exclude = [self]

var result = space_state.intersect_ray(query)

if result and result.has("collider"):
	var obj = result.collider

	if obj.is_in_group("interactable"):
		return obj

	if obj.has_method("interact"):
		return obj

return null

func _update_interaction_ui():
prompt.visible = _get_interactable() != null

func _try_interact():
var obj = _get_interactable()

if obj and obj.has_method("interact"):
	obj.interact()


Which part exactly is the problem?
What happens vs what do you want to happen?

Also, your code got flattened when you pasted it (the indentation is not correct), can you edit your post to fix it?

1 Like

I’m not sure what the problem is; you mention ‘stepping’, but I see ‘stepping’ nowhere in the code. Did you mean ‘sprinting’..?
The ‘sprint’ stamina will be reduced by 25, 60 times a second, from a maximum of 100, down to a minimum of 5. That’s not much time for sprinting..! Try a stamina maximum of 10,000, and see what happens..?

stepping as in you go up when you try to go on a surface a lil higher

im new to this so i dont really know how to un-flatten it.
the problem is that i dont go up when i try to go on a surface little higher, what happens is that nothing happens and what i want is when you go on a surface a little higher it moves the player up

Where is the part of the code that’s suppose to do that?

do you mean trying to go up stairs?

yea pretty much

i removed that part for the time being

this post I previously made can help redo the collision so you can do it without a whole bunch of code checking that their is a stair (it is honestly not an easy problem to solve)

1 Like

this works yes but there are parts in my game where theres cubes that have elevation, but not like in a stair way

below my post @Frozen_Fried provided a nice video explaining the different logics you would need to think about when thinking about staris

2 Likes

As othe rpeople stated, Godot CharacetrBody3D can not handle steps. There are several options, but without native support are all patches.

I as many created my own ‘patch‘, you can find it at this repo: https://github.com/walterpalladino/godot-tps-controller as CharacterController3D with support for steps.

There are several examples in the project of this controller working on 3rd and 1st person.

I hope could be of use for you.

An easier solution if you’re ok with a little faking is to change the stairs’ collision shape to be a ramp. You can also play around with CharacterBody3D’s Max Angle setting. Though if you’re not careful, you can allow them to walk up walls. Still both are simpler solutions than raycasts. Also a capsule shaped collision shape that’s large enough to overcome the lip of a stair will solve the problem. So that’s three non-code options to explore.

1 Like

The Player in my 3d Dungeon game has an upright ‘capsule’ collision shape, and has no trouble climbing or descending stairs between Levels in the Dungeon. There is no ‘bobbing’ motion on such stairs, but that’s OK for me. The Player can stop on the stairs, and turn around; there is no code required, just the standard ‘move and glide’. Just sayin’. :slight_smile:

1 Like