A more complex camera

Hello! I’m on the onion design episode/lecture, and its talking about tightening up your camera. I actually went out and found a camera that did ALMOST everything I want to do. My goal is an ARPG with a camera view more closely resembling an MMO. It does everything I want, except two things…

  1. Right now, it doesn’t stay behind the player. It follows the player, but does not stay behind. If I click to the left with our click to move design, the player turns left, but the camera does not stay behind him, turning the view. I can however fix this using the right mouse button (you’ll see in the code).

  2. I want to be able to use the right mouse button to custom move the camera, to be able to spin it to see the front of the character (if they equip an awesome piece of new gear and want to see what their character looks like for example. But, when the player lets go of the right mouse button, I want the camera to snap back to where it should be, behind the player.

Here is the current code I’m working with:

using UnityEngine;
using System.Collections;

public class CamaraJugador : MonoBehaviour
{
    public Transform CameraTarget;
    private float x = 0.0f;
    private float y = 0.0f;

    private int mouseXSpeedMod = 5;
    private int mouseYSpeedMod = 5;

    public float MaxViewDistance = 15f;
    public float MinViewDistance = 1f;
    public int ZoomRate = 20;
    private int lerpRate = 5;
    private float distance = 3f;
    private float desireDistance;
    private float correctedDistance;
    private float currentDistance;

    public float cameraTargetHeight = 1.0f;

    //checks if first person mode is on
    private bool click = false;
    //stores cameras distance from player
    private float curDist = 0;

    // Use this for initialization
    void Start()
    {
        Vector3 Angles = transform.eulerAngles;
        x = Angles.x;
        y = Angles.y;
        currentDistance = distance;
        desireDistance = distance;
        correctedDistance = distance;
    }

    // Update is called once per frame
    void LateUpdate()
    {
        if (Input.GetMouseButton(1))
        {/*0 mouse btn izq, 1 mouse btn der*/
            x += Input.GetAxis("Mouse X") * mouseXSpeedMod;
            y += Input.GetAxis("Mouse Y") * mouseYSpeedMod;
        }
        else if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
        {
            float targetRotantionAngle = CameraTarget.eulerAngles.y;
            float cameraRotationAngle = transform.eulerAngles.y;
            x = Mathf.LerpAngle(cameraRotationAngle, targetRotantionAngle, lerpRate * Time.deltaTime);
        }

        y = ClampAngle(y, -15, 25);
        Quaternion rotation = Quaternion.Euler(y, x, 0);

        desireDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * ZoomRate * Mathf.Abs(desireDistance);
        desireDistance = Mathf.Clamp(desireDistance, MinViewDistance, MaxViewDistance);
        correctedDistance = desireDistance;

        Vector3 position = CameraTarget.position - (rotation * Vector3.forward * desireDistance);

        RaycastHit collisionHit;
        Vector3 cameraTargetPosition = new Vector3(CameraTarget.position.x, CameraTarget.position.y + cameraTargetHeight, CameraTarget.position.z);

        bool isCorrected = false;
        if (Physics.Linecast(cameraTargetPosition, position, out collisionHit))
        {
            position = collisionHit.point;
            correctedDistance = Vector3.Distance(cameraTargetPosition, position);
            isCorrected = true;
        }

        //?
        //condicion ? first_expresion : second_expresion;
        //(input > 0) ? isPositive : isNegative;

        currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * ZoomRate) : correctedDistance;
        position = CameraTarget.position - (rotation * Vector3.forward * currentDistance + new Vector3(0, -cameraTargetHeight, 0));

        transform.rotation = rotation;
        transform.position = position;

        //CameraTarget.rotation = rotation; 

        float cameraX = transform.rotation.x;


        //checks if right mouse button is pushed
              if (Input.GetMouseButton(1))
              {
                  //sets CHARACTERS x rotation to match cameras x rotation
                  CameraTarget.eulerAngles = new Vector3(cameraX, transform.eulerAngles.y, transform.eulerAngles.z);
               }
               //checks if middle mouse button is pushed down
              if (Input.GetMouseButtonDown(2))
             {
                  //if middle mouse button is pressed 1st time set click to true and camera in front of player and save cameras position before mmb.
                  //if mmb is pressed again set camera back to it's position before we clicked mmb 1st time and set click to false
                   if (click == false)
                  {
                      click = true;
                       curDist = distance;
                       distance = distance - distance - 1;
                   }
                   else
                   {
                       distance = curDist;
                       click = false;
                   }
               }

          }

        private 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);
        }
    }

Privacy & Terms