How to rotate character based on wall normal for a wall slide animation?

Godot Version

4

Question

I want to rotate the player based on the wall surface he touches so that I can make the character slide onto the wall.

I have a script, it’s supposed to get the wall normal and use it to change the rotation of the player so that It can rotate to the normal.

wall_norm.normal results in Invalid get index ‘normal’ (on base: ‘KinematicCollision3D’).

wall_norm = get_slide_collision(0)
		
model.rotation.y = wall_norm.normal
		

use wall_norm.get_normal()

When I change it to

wall_norm = get_slide_collision(0)
model.rotation = wall_norm.get_normal()

The character turns to it’s side and faces the right side for one side of the wall but for the other still faces the wrong way

Can you show more code or a picture? Node3D’s rotation property is in radians how much each axis rotates, a normal value being plugged into this will basically never be useful. My first thought is to use look_at with the normal as the UP direction and then make the character look the direction they are moving.

var wall_norm := get_slide_collision(0).get_normal()
var forward := velocity + global_position
model.look_at(forward, wall_norm)
	move_and_slide()
		
	if is_on_wall() and not is_on_floor():
		anim_tree.set("parameters/conditions/slidingonwall", true)
		anim_tree.set("parameters/conditions/jumping", false)
		anim_tree.set("parameters/conditions/grounded", false)
		
		var wall_norm := get_slide_collision(0).get_normal()
		var forward := velocity + global_position
		
		model.look_at(forward, wall_norm)
		
		can_walljump = true

lookat
causes the character to slide onto the wall sideways, causing only the character’s feet to be touching the wall during the animation
https://i.imgur.com/sYBmG0K.png
I’m looking for a result like this


Maybe we need to rotate the lookat so that the player faces up?

Up to how you animate. You will need to play around with look_at or find a new equation that works for your animation.

Going back to your original idea we could get an angle for just the Y axis based on the normal vector. This will look strange for walls that are slanted; rather than straight up.

var wall_norm := get_slide_collision(0).get_normal()

var y_rotation := atan2(wall_norm.y, wall_norm.x)
model.rotation.y = y_rotation

It worked, my character model is facing up with the right rotation from the wall!

How would I have velocity away from the wall now?