Limit character head rotation

Hello.
I have a character who look at the point where the cursor is. Now he rotate a head 360 degrees
in all axes.
And i wont to limit X,Y rotation. I dont know how to do that.

public class HeadLook : MonoBehaviour
{
public LayerMask layerIgnore;
public Camera cam;
public GameObject head;
public Vector3 limit;
private RaycastHit hit;

private void LateUpdate()
{
    followCursor();
}

private void followCursor()
{
    Vector3 cursorPosition = Input.mousePosition;
    Ray ray = cam.ScreenPointToRay(cursorPosition);

    if (Physics.Raycast(ray, out hit, 500f, ~layerIgnore))
    {
        head.transform.LookAt(hit.point);
    }
}

}

This is a different approach that might work for you. Move an empty gameobject to the mouse position and add constraints to that movement, and then just add a transform.LookAt to your head to look at that point.


The script for the point is this:

using UnityEngine;

public class PointToLookAt : MonoBehaviour
{
    public float posMultiplier = 3f;
    public float pointDepth = 0.2f;
    public bool lockX;
    public bool lockY;
    public Camera cam;

    void Update()
    {
        Vector3 mousePos = Input.mousePosition * posMultiplier;
        mousePos.z = pointDepth;
        Vector3 target = cam.ScreenToWorldPoint(mousePos);

        if (lockX)
        {
            target.x = 0;
        }
        if (lockY)
        {
            target.y = 0;
        }
        transform.position = target;
    }
}

Simple LookAt for the head:

using UnityEngine;

public class LookAtTarget : MonoBehaviour
{
    public Transform target;

    void Update()
    {
        transform.LookAt(target.position);
    }
}

And in the Inspector it will look like this for the point:
160071-unity-script-to-move-point-to-mouse-position-with.png


And like this for the simple LookAt on the head:
160072-unity-simple-lookat-script.png

Here is yet another method:

 float x;
 float y;

 private void Update()
 {
     x -= Input.GetAxisRaw("Mouse Y") * moveSensitivity * Time.deltaTime;
     y += Input.GetAxisRaw("Mouse X") * moveSensitivity * Time.deltaTime;
     x = Mathf.Clamp(x, -90, 90);
     transform.rotation = Quaternion.Euler(x, y, 0);
 }

}

In this tutorial you will find all you need :slight_smile:

Thanks @Fkat and @tadadosi I don’t know if these solutions would help in my case because now I was able to solve the problem.
This Turret rotation based on its own local rotation. - Questions & Answers - Unity Discussions
help me so much.

my code now:

using UnityEngine;
public class HeadLook : MonoBehaviour
{
public LayerMask layerIgnore;
public Camera cam;
public GameObject head;
public Vector3 limit;
public float smooth;
private Vector3 target;
private RaycastHit hit;
private Vector3 normal;
private void LateUpdate()
{
    followCursor();
}
private void followCursor()
{
    Vector3 cursorPosition = Input.mousePosition;
    Ray ray = cam.ScreenPointToRay(cursorPosition);

    normal = transform.forward;

    if (Physics.Raycast(ray, out hit, 100f, ~layerIgnore))
    {
        Vector3 desiredPosition = new Vector3(hit.point.x, hit.point.y, hit.point.z);
        Vector3 smoothedPosition = Vector3.Lerp(target, desiredPosition, smooth);
        target = smoothedPosition;

        Vector3 direction = target - head.transform.position;
        Debug.DrawRay(head.transform.position, direction, Color.blue);

        float angle = Vector3.Angle(normal, direction.normalized);

        Vector3 axis = Vector3.Cross(normal, direction.normalized);          

        Vector3 targetDir = Quaternion.AngleAxis(Mathf.Clamp(angle, -limit.x, limit.x), axis) * normal;
        Debug.DrawRay(transform.position, targetDir, Color.red);

        Quaternion targetRotation = Quaternion.LookRotation(targetDir);
        head.transform.rotation = Quaternion.Slerp(head.transform.localRotation, targetRotation, 1);                       
    }       
}