The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

0 votes

I have been working on building climbing mechanics for a 3d adventure platformer. Through piecing together from multiple tutorials I was able to get something similar to what I wanted. However when I tried to have the player character climb around on the outside of a corner greater than 90 degrees that is where the issues lie.

One of the issues (and the main one) I ran into is when the player is going around the corner he flips between two normal values, causing the character to 'spaz' out. It isn't that uncommon for the Player to get rotated away from climbable object and just be floating in mid air. I originally thought it was because I was using two separate objects to get the corner, but through testing with a collision ConvexPolygonShape I got the same results.

The other issue is a minor one compared to the previous one. If I have the player climb down at the backside of the climbable object it will occasionally pickup strange normal values. The character then starts to twitch for a little while climbing straight down. Works perfectly find if you're doing it from the front of the object

The way I have it working is that 3 raycasts are used to get the normal position. One at the center, one going 15 degrees to the left, and the last going 15 degrees to the right. I then take the 3 values and Lerp the values down to one variable. That variable is then used to determine the players orientation and facing direction when climbing.

here is code I'm using

in the input (event) function

    if player_state == 2:
    if event is InputEventMouseMotion:
        return climbDir
    else:
        var Climb_Face_L = lerp(climbCast02.get_collision_normal(), climbCast_C.get_collision_normal(), .5)
        var Climb_Face_R = lerp(climbCast01.get_collision_normal(), climbCast_C.get_collision_normal(), .5)
        climbDir = lerp(Climb_Face_L, Climb_Face_R, .5)
        printt(climbDir.x, climbDir.z)

The Climb process function placed in the physics process

func _Climb_process(delta):


climbDir.y = 0
gravity = 0
walk_speed = .75
sprint_speed = 2

var z = -1 * climbDir
var x = climbDir.cross(Vector3.UP).normalized()
var y = z.rotated(x, -PI/2)


character.transform.basis = Basis(x, y, z)
var H_rotation = character.global_transform.basis.get_euler().y


if Input.is_action_pressed("Forward") || Input.is_action_pressed("Back") || Input.is_action_pressed("Left") || Input.is_action_pressed("Right"):
    direction = Vector3(Input.get_action_strength("Left") - Input.get_action_strength("Right"),
     Input.get_action_strength("Forward") - Input.get_action_strength("Back"),
    0)

    direction = direction.rotated(Vector3.UP, H_rotation).normalized()

I can provide Images and or more code if needed

Godot version 3.5
in Engine by (12 points)

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.