(3D KinematicBody) lock rotation axis when using look_at()?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By spiderbyte87

After wrestling with it for many hours, here’s my solution to getting my third-person controller to look at the mouse in 3D:

extends KinematicBody

func _input(event):
    if event is InputEventMouseMotion:
        var camera = get_node("../Camera")
        var from = camera.project_ray_origin(event.get_position())
        var to = from + camera.project_ray_normal(event.get_position()) * 1000
        var space_state = get_world().direct_space_state
        var ray = space_state.intersect_ray(from, to, [self,$guns],1, true, true)
        var rayPOS = ray.get("position",Vector3(0,1,0))
        if rayPOS.y != 0: #prevents look_at() alignment error 
            self.look_at(rayPOS,Vector3(0,1,0))

It works great, it’s fast, and (I think) it’s elegant. I would like to only rotate on the Y axis though.

Is there some way to lock the rotation on a certain axis without resorting to a dirtier solution?

When you want to lock the rotation to one of the axises, have you considered assigning “0” to two of the axises? For example, to rotate on the y-axis, assign (I think) 0 to the"x" and “z” components of the transformation.

Ertain | 2019-09-01 23:28

Yeah I tried that in look_at() but it doesn’t work. I think I’m going to calculate the angle from the player to the ray intersect and do a rotation. Look_at() is cool but not what I need I think.

spiderbyte87 | 2019-09-01 23:47

If you want it to turn only on the y axis you have to make it look at an object that is the same height as itself. so set rayPOS.y = get_global_transform().origin.y, and than look at rayPOS. It will only rotate on y axis.

gmaps | 2019-09-02 07:25

Yep that’s exactly what I ended up doing and it worked perfectly!

spiderbyte87 | 2019-09-03 15:07

:bust_in_silhouette: Reply From: spiderbyte87

This is the answer, copied from user gmaps comment: If you want it to turn only on the y axis you have to make it look at an object that is the same height as itself. so set rayPOS.y = get_global_transform().origin.y, and than look at rayPOS. It will only rotate on y axis.