Camera Script - Following an Object's Rotation (X axis only) - Please help

Hey there, everyone. I have been working on a script which is on my MainCamera. It follows the player as soon as he spawns. It also rotates with him. However, I wish for the camera to only rotate its X axis (Left/Right) along with the player, while still allowing the Y axis to move freely.
The script on my main camera is this simple piece of code:

using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour {
   
    public GameObject target;
    private Vector3 offset;
    private Vector3 HeightPos = new Vector3 ((float)0,(float)3,(float)0);
   
    // Use this for initialization
    void Start () {
        offset = transform.position;
    }
   
    // Update is called once per frame
    void LateUpdate () {
        if (target != null){
            transform.position = target.transform.position + offset+HeightPos;
            transform.rotation = target.transform.rotation;
        }
    }
}

The camera sits on my player’s face (And gives a first-person perspective), and while it turns with it perfectly, I cannot look up/down, even with other code attached to the camera, such as the MouseLook sample script. I believe this is because the camera is setting itself all the time the player’s Y and Z rotations as well, which I do not want. How do I get the rotation to update so only the X axis is rotated along with the player?

Here is a script that will move the camera up and down using the mouse, and will set the x rotation to the target’s x rotation.

using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour {

    public Transform target;
    public Vector3 HeightPos = new Vector3 (0f, 3f, 0f);
    public float ySpeed = 2.4f;
    public float yMinLimit = -20;
    public float yMaxLimit = 80;
 
    private float y;

    void Start(){
        y = transform.eulerAngles.y;
    }
 
    void LateUpdate () {
        if (target != null){
            y -= Input.GetAxis("Mouse Y") * ySpeed;
            y = ClampAngle (y, yMinLimit, yMaxLimit);
            transform.position = target.position + HeightPos;
            transform.rotation = Quaternion.Euler(y, target.eulerAngles.x, 0);
        }
    }
 
    static float ClampAngle (float angle, float min, float max) {
        if (angle < -360)
            angle += 360;
        if (angle > 360)
            angle -= 360;
        return Mathf.Clamp (angle, min, max);
    }
}
1 Like

Hey. Thank you very much for helping me out with this one! The y axis turn is looking very nice! As for the X axis… for some reason the camera isn’t turning with the player anymore. It’s okay, I’ll try to find a solution. Once I do, I’ll post it here. Once again, thanks for your help :slight_smile:

I just updated the code in my above post. Try the updated script.

Hey. Sorry to tell you, but the problem seems to keep persisting. I also noticed that it’s specifically this code that stops the camera from turning after the player spawns. I saw this because that before the player spawns, the MainCamera object is still there (It is set to follow him locally when he spawns), and during this time I can move the camera left and right. However, as soon as the player spawns and the camera goes into his perspective, he cannot turn his head.
I am really sorry to bother you with my problems. I know I am not very helpful at explaining or doing anything. I am still new to this : /

What script are you using to move the player?

using UnityEngine;
using System.Collections;

public class PlayerMov : MonoBehaviour {
    //Variables
    public float speed = 6.0F;
    public float jumpSpeed = 8.0F;
    public float gravity = 20.0F;
    private Vector3 moveDirection = Vector3.zero;

    public bool IsPlayer1;
   
    void Update() {
        if (IsPlayer1){

            transform.Rotate(0,Input.GetAxis("Rotate")*120f*Time.deltaTime,0);
            CharacterController controller = GetComponent<CharacterController>();
            // is the controller on the ground?
            if (controller.isGrounded) {
                //Feed moveDirection with input.
                moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
                moveDirection = transform.TransformDirection(moveDirection);
                //Multiply it by speed.
                moveDirection *= speed;
                //Jumping
                if (Input.GetButton("Jump"))
                    moveDirection.y = jumpSpeed;
               
            }
            //Applying gravity to the controller
            moveDirection.y -= gravity * Time.deltaTime;
            //Making the character move
            controller.Move(moveDirection * Time.deltaTime);
            return;
        }


    }
}

Basically, it only works if the player confirms that they are controlling themselves (And not the other players - it’s a multiplayer game.)

For rotations, quaternions better manipulate directly, instead of rotating from Transform.

I added a zoom. And I created an object called MinMax to obtain values in a range.

You can also adjust both the offset relative to the position of the target, as the offset to focus.

This is the code:

using UnityEngine;
using System.Collections;


[System.Serializable]
public class MinMax{

    public float min;
    public float max;

    public MinMax(float min,float max){

        this.min = Mathf.Min(min,max);
        this.max = Mathf.Max(min,max);

    }

    public float Clamp (float value){ return Mathf.Clamp(value,this.min,this.max); }
    public float Repeat(float value){ return this.min + Mathf.Repeat(value-this.min,this.max-this.min); }

}


[RequireComponent(typeof(Camera))]
public class CameraController : MonoBehaviour {
   
    public Transform target;
    public Vector3 offSetLookAt   = new Vector3(0f,1f,   0f);
    public Vector3 offSetPosition = new Vector3(0f,3f,-2.5f);
    public MinMax MinMaxRotationX = new MinMax(-45f,3f); //Up-Down rotation
    public MinMax MinMaxRotationY = new MinMax(-90f,90f); //Left-Right rotation
    public MinMax MinMaxCameraDistance = new MinMax(5f,20f); //Zoom distance

    public float angleX = -10f; //Up-Down angle
    public float angleY = 0f; //Left-Right angle
    public float cameraDistance=5f;

    Vector3 normal; //OffSetPosition normalized

    void Start(){

        if(target==null){

            Debug.Log("Add target to CameraController script");
            Destroy(this);

        } else {

            normal = offSetPosition.normalized;

        }

    }
   
    void Update () {

        this.angleX = MinMaxRotationX.Clamp(this.angleX-Input.GetAxis("Mouse Y"));
        this.angleY = MinMaxRotationY.Clamp(this.angleY+Input.GetAxis("Mouse X"));
        this.cameraDistance = MinMaxCameraDistance.Clamp(this.cameraDistance+Input.GetAxis("Mouse ScrollWheel")*10f);

        Quaternion upRotation = Quaternion.LookRotation(new Vector3(target.forward.x,0f,target.forward.z))*Quaternion.Euler(0f,this.angleY,0f);
        transform.position = target.position + upRotation*normal*this.cameraDistance;
        transform.rotation = Quaternion.LookRotation((target.position+offSetLookAt)-transform.position)*Quaternion.Euler(this.angleX,0f,0f);

    }

}

Download link.