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

Attention Topic was automatically imported from the old Question2Answer platform.

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