Need help with camera script!

Hello :slight_smile:
I am trying to create a third person shooter and I want a camera system as seen in Metal Gear Solid 5.
What I have now is the camera orbiting and following the player. I want to have it so when I hold right click, the camera zooms over the character shoulder and the camera follows the mouse.

Here is my current Camera Script (attached to the main camera)
ShooterGameScript.cs:

using UnityEngine;
using System.Collections;

// 3rd person game-like camera controller
// keeps camera behind the player and aimed at aiming point
public class ShooterGameCamera : MonoBehaviour {

    public Transform player;
    public Texture crosshair;

    protected Transform aimTarget; // that was public and a gameobject had to be dragged on it. - ben0bi

    public float smoothingTime = 10.0f; // it should follow it faster by jumping (y-axis) (previous: 0.1 or so) ben0bi
    public Vector3 pivotOffset = new Vector3(0.2f, 0.7f,  0.0f); // offset of point from player transform (?) ben0bi
    public Vector3 camOffset   = new Vector3(0.0f, 0.7f, -3.4f); // offset of camera from pivotOffset (?) ben0bi
    public Vector3 closeOffset = new Vector3(0.35f, 1.7f, 0.0f); // close offset of camera from pivotOffset (?) ben0bi

    public float horizontalAimingSpeed = 800f;
    public float verticalAimingSpeed = 800f;
    public float maxVerticalAngle = 80f;
    public float minVerticalAngle = -80f;
  
    public float mouseSensitivity = 0.3f;

    private float angleH = 0;
    private float angleV = 0;
    private Transform cam;
    private float maxCamDist = 1;
    private LayerMask mask;
    private Vector3 smoothPlayerPos;

    // Use this for initialization
    void Start ()
    {
        //3 lines from mouseLook
        Vector3 rot = transform.localRotation.eulerAngles;
        rotY = rot.y;
        rotX = rot.x;
        // [edit] no aimtarget gameobject needs to be placed anymore - ben0bi
        GameObject g=new GameObject();
        aimTarget=g.transform;
        // Add player's own layer to mask
        mask = 1 << player.gameObject.layer;
        // Add Igbore Raycast layer to mask
        mask |= 1 << LayerMask.NameToLayer("Ignore Raycast");
        // Invert mask
        mask = ~mask;

        cam = transform;
        smoothPlayerPos = player.position;

        maxCamDist = 3;
    }

    // Update is called once per frame
    void LateUpdate () {
        if (Time.deltaTime == 0 || Time.timeScale == 0 || player == null)
            return;
   
        angleH += Mathf.Clamp(Input.GetAxis("Mouse X") /* + Input.GetAxis("Horizontal2") */ , -1, 1) * horizontalAimingSpeed * Time.deltaTime;
   
        angleV += Mathf.Clamp(Input.GetAxis("Mouse Y") /* + Input.GetAxis("Vertical2") */ , -1, 1) * verticalAimingSpeed * Time.deltaTime;
        // limit vertical angle
        angleV = Mathf.Clamp(angleV, minVerticalAngle, maxVerticalAngle);

        // Before changing camera, store the prev aiming distance.
        // If we're aiming at nothing (the sky), we'll keep this distance.
        float prevDist = (aimTarget.position - cam.position).magnitude;

        // Set aim rotation
        Quaternion aimRotation = Quaternion.Euler(-angleV, angleH, 0);
        Quaternion camYRotation = Quaternion.Euler(0, angleH, 0);
        cam.rotation = aimRotation;

        // Find far and close position for the camera
        smoothPlayerPos = Vector3.Lerp(smoothPlayerPos, player.position, smoothingTime * Time.deltaTime);
        smoothPlayerPos.x = player.position.x;
        smoothPlayerPos.z = player.position.z;
        Vector3 farCamPoint = smoothPlayerPos + camYRotation * pivotOffset + aimRotation * camOffset;
        Vector3 closeCamPoint = player.position + camYRotation * closeOffset;
        float farDist = Vector3.Distance(farCamPoint, closeCamPoint);

        // Smoothly increase maxCamDist up to the distance of farDist
        maxCamDist = Mathf.Lerp(maxCamDist, farDist, 5 * Time.deltaTime);

        // Make sure camera doesn't intersect geometry
        // Move camera towards closeOffset if ray back towards camera position intersects something
        RaycastHit hit;
        Vector3 closeToFarDir = (farCamPoint - closeCamPoint) / farDist;
        float padding = 0.3f;
        if (Physics.Raycast(closeCamPoint, closeToFarDir, out hit, maxCamDist + padding, mask)) {
            maxCamDist = hit.distance - padding;
        }
        cam.position = closeCamPoint + closeToFarDir * maxCamDist;

        // Do a raycast from the camera to find the distance to the point we're aiming at.
        float aimTargetDist;
        if (Physics.Raycast(cam.position, cam.forward, out hit, 100, mask)) {
            aimTargetDist = hit.distance + 0.05f;
        }
        else {
            // If we're aiming at nothing, keep prev dist but make it at least 5.
            aimTargetDist = Mathf.Max(5, prevDist);
        }

        // Set the aimTarget position according to the distance we found.
        // Make the movement slightly smooth.
        aimTarget.position = cam.position + cam.forward * aimTargetDist;
    }


    void Update()
    {
        if (Input.GetKey ("mouse 1")) {
            camOffset = new Vector3 (0.0f, 0.8f, -1.7f);
            float horizontalAimingSpeed = 0f;
            float verticalAimingSpeed = 0f;
        } else
        {
            camOffset = new Vector3(0.0f, 0.7f, -3.4f);
            float horizontalAimingSpeed = 400f;
            float verticalAimingSpeed = 400f;
        }
    }


    // so you can change the camera from a static observer (level loading) or something else
    // to your player or something else. I needed that for network init... ben0bi
    public void SetTarget(Transform t)
    {
        player=t;
    }

    void OnGUI ()
    {
        if (Time.time != 0 && Time.timeScale != 0)
            GUI.DrawTexture(new Rect(Screen.width/2-(crosshair.width*0.5f), Screen.height/2-(crosshair.height*0.5f), crosshair.width, crosshair.height), crosshair);
    }

}

I’ve got the camera to zoom in over his shoulder when I hold right mouse button.
I really have no idea on where to start on this?
Any help would be greatly appreciated!
Cheers.

This should cover the zoom part then you just use the mouse x position and y position to turn the player like the a and d keys do. The input settings already have a mouse x and y axis.

Thanks, but then I need to disable the original mouse look script, right? Or or else both the scripts will interfere with each other?

sorry for the late response. i have been busy the last 2 days. i would just place your script in the place of the tpsOffset and see how that works for now. you will need to add the mouse movement to the fpsOffset side of the if statement as well. these are design questions though. as long as you are within your happy with the way it works and the game performs well on the target platforms there really is no wrong answer.

Thanks, I am using your TPSOffset script now and it’s good! But do you know how I can aim with freelook when ADS? So when I’m walking around normally the camera is in orbit and when I ADS I can look horizontally and vertically with the mouse? If you understand What I’m saying…

Like In The Division
https://www.youtube.com/watch?v=h4GxWdA6ZNo

the script in the other forum is very bare bones. what you will want to do is if you are aiming then use the mouse x and y to turn the character instead of the camera. then the camera will fall in line. this maybe better implemented in the player controller than a camera script. using vertical 1 for forward and back movement in both aim modes. use horizontal1 for turning when not aiming but for strafing when aiming. vertical 2 is up and down looking in both while horizontal 2 turns the camera alone when not aiming but both the camera and character when aiming. I would probably have different methods for each and call them as needed from the update function based on input.