Snowboard gravity and slope logic

Godot Version

4.3

Question

First time Godot user alert. I have made a player from a characterBody3d node with a meshInstance3d and CollisionShape3d. It spawns above a slope, I am trying to get it to slide down the slope. Currently it falls to the ground then stops.

I would expect the character to slide down the slope at 9.8cosAngle but nothing. Is there a setting for friction or a material property I can add. Sadly chatGPT is useless with godot 4. Do I use move_and_slide ? move_and_collide and fake gravity ?

I had tried the below but i only got the character to accelerate up the slope and with -gravity it would just be still:

func _physics_process(delta: float) -> void:
 var collision_info = move_and_slide(velocity, Vector3.UP) 
  if collision_info: 
    var slope_normal = collision_info.get_normal() 
    print("Slope Normal: ", slope_normal) 

    # Calculate gravity direction 
    var gravity_direction = Vector3(0, gravity,0).slide(slope_normal).normalized() 
    print("Gravity Direction: ", gravity_direction) 

   var gravity_force = gravity_direction * gravity * delta 
    print("Gravity Force: ", gravity_force) 

    velocity += gravity_force 

   # Clamp to max speed 
    velocity.x = clamp(velocity.x, -max_speed, max_speed) 
    velocity.z = clamp(velocity.z, -max_speed, max_speed)
  else: 
    # Apply gravity when in the air 
    velocity.y += gravity * delta 
# Move the character 
  move_and_slide() 
# Debug current velocity
 print("Velocity: ", velocity)Vector3.ZERO

I fixed it:

extends CharacterBody3D

@export var max_speed = 20
@export var gravity = Vector3(0, -9.8, 0)
@export var acceleration := 2.0
@export var max_fall_speed = 30


func _physics_process(delta: float) -> void:
	if is_on_floor():
		var floor_normal = get_floor_normal()

		var gravity_direction: Vector3 = gravity.normalized()
		var downhill_direction: Vector3 = gravity_direction.slide(floor_normal).normalized()
		print("Downhill Direction:", downhill_direction)
		# Calculate acceleration along the slope
		var slope_acceleration: Vector3 = downhill_direction * gravity.length()

		# Apply acceleration to velocity
		velocity += slope_acceleration * delta
		if velocity.length() > max_speed:
			velocity = velocity.normalized() * max_speed
	else :
		velocity += gravity * delta
		if velocity.length() > max_fall_speed:
			velocity = velocity.normalized() * max_fall_speed

	move_and_slide()
	print("Velocity:", velocity)

If this follows any bad practises or patterns I would love to learn about them!

You can try using physics material.

Godot Physics Material

If gravity doesn’t change then it’s unnecessary to calculate gravity_direction every frame, since it will always be the same too. You could just declare it outside of _physics_process.

Or, since you use gravity length anyway, no need to normalize it first.
I think you could simply do this (but I haven’t tested so not 100% sure…):
var slope_acceleration: Vector3 = gravity.slide(floor_normal)

But as mentioned by almusx, move_and_slide should make your character slide down a slope if you set up the materials and your character body properly (but I don’t really know how to do that exactly…)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.