When player climbs on a wall, the forward direction may not be perpendicular to the wall plane, which will result in weired animation. I want adjust the character's rotation at the moment FSM changes to climb state. I tried a few ways but none of them works including:

1. change the basis.z with -1 * collision normal

2. look at the collision point (I know why this fails because if the forward direction is not perpendicular to the wall the look_at won't work. If it is perpendicular there's no need to look at)

I'm new here and a newbie to gamedev. I'm very grateful if you are willing to offer some help.

Godot version 3.5.beta
in Engine

this works perfect when climbing on a cube whose faces are not bevel.

What about bevel cases where the y component is no longer Vector3.UP

Someone on Reddit gives me the solution, here is the code:

```
var z = -1 * normal
var x = normal.cross(Vector3.UP).normalized()
var y = z.rotated(x, -PI/2)
character.rotation_helper.transform.basis = Basis(x, y, z)
```

The point is getting x by z-up plane
and getting y axis by rotating z around x by -90 degree
by (37 points)
edited

using this function it returns a new transform

``````func align_with_y(xform, new_y):
xform.basis.y = new_y
xform.basis.x = -xform.basis.z.cross(new_y)
xform.basis = xform.basis.orthonormalized()
return xform
``````

xfrom is the current transform and new_y is the normal (i suggest using a raycast normal) you want to be oriented at

``````global_transform = align_with_y(global_transform, \$raycast.get_collision_normal())
``````
by (458 points)

It turns out to be this:

before hit the wall:

after hit the wall:

Here is how I use this snippet:

```func activated(_message := {}) -> void:
var normal = character.climber.get_chest_collision_normal()
var global_transform = character.rotation_helper.global_transform
character.rotation_helper.global_transform = align_with_y(global_transform, normal)

func align_with_y(xform, new_y):
xform.basis.y = new_y
xform.basis.x = -xform.basis.z.cross(new_y)
xform.basis = xform.basis.orthonormalized()
return xform
```

the only thing i can suggest because your images are not showing is to change

``````character.rotation_helper.global_transform = align_with_y(global_transform, normal)
``````

to

``````character.rotation_helper.global_transform = align_with_y(character.rotation_helper.global_transform, normal)
``````