Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Camera Script Question

Discussion in 'Scripting' started by DanielX95, Jul 5, 2017.

  1. DanielX95

    DanielX95

    Joined:
    Apr 25, 2017
    Posts:
    24
    Hi guys,

    i have been developing a 3D fantasy game for PC/Mac, and i have a player character in third person.
    My goal for the main camera is that it follows the player everywhere and that the player can rotate it around the the character with the mouse.
    For the second purpose i've found this script online and it works properly, but now, how can i make the camera follow the player always at the same distance from it?

    Best regards and thanks for your time.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5.  
    6. public class CameraRotate : MonoBehaviour {
    7.  
    8.     public float turnSpeed = 4.0f;        // Speed of camera turning when mouse moves in along an axis
    9.     public float panSpeed = 4.0f;        // Speed of the camera when being panned
    10.     public float zoomSpeed = 4.0f;        // Speed of the camera going back and forth
    11.  
    12.     private Vector3 mouseOrigin;    // Position of cursor when mouse dragging starts
    13.     private bool isPanning;        // Is the camera being panned?
    14.     private bool isRotating;    // Is the camera being rotated?
    15.     private bool isZooming;        // Is the camera zooming?
    16.  
    17.     //
    18.     // UPDATE
    19.     //
    20.  
    21.     void Update ()
    22.     {
    23.         // Get the left mouse button
    24.         if(Input.GetMouseButtonDown(0))
    25.         {
    26.             // Get mouse origin
    27.             mouseOrigin = Input.mousePosition;
    28.             isRotating = true;
    29.         }
    30.  
    31.         // Get the right mouse button
    32.         if(Input.GetMouseButtonDown(1))
    33.         {
    34.             // Get mouse origin
    35.             mouseOrigin = Input.mousePosition;
    36.             isPanning = true;
    37.         }
    38.  
    39.         // Get the middle mouse button
    40.         if(Input.GetMouseButtonDown(2))
    41.         {
    42.             // Get mouse origin
    43.             mouseOrigin = Input.mousePosition;
    44.             isZooming = true;
    45.         }
    46.  
    47.         // Disable movements on button release
    48.         if (!Input.GetMouseButton(0)) isRotating=false;
    49.         if (!Input.GetMouseButton(1)) isPanning=false;
    50.         if (!Input.GetMouseButton(2)) isZooming=false;
    51.  
    52.         // Rotate camera along X and Y axis
    53.         if (isRotating)
    54.         {
    55.             Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
    56.  
    57.             transform.RotateAround(transform.position, transform.right, -pos.y * turnSpeed);
    58.             transform.RotateAround(transform.position, Vector3.up, pos.x * turnSpeed);
    59.         }
    60.  
    61.         // Move the camera on it's XY plane
    62.         if (isPanning)
    63.         {
    64.             Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
    65.  
    66.             Vector3 move = new Vector3(pos.x * panSpeed, pos.y * panSpeed, 0);
    67.             transform.Translate(move, Space.Self);
    68.         }
    69.  
    70.         // Move the camera linearly along Z axis
    71.         if (isZooming)
    72.         {
    73.             Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
    74.  
    75.             Vector3 move = pos.y * zoomSpeed * transform.forward;
    76.             transform.Translate(move, Space.World);
    77.         }
    78.     }
    79. }
    80.  
     
  2. radwan92

    radwan92

    Joined:
    Sep 6, 2013
    Posts:
    56
    You can attach your camera to the player object in the hierarchy. That should do
     
  3. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    I think what would help you most is knowing what that script does versus what your camera is supposed to be doing.

    so, mouse 0 is the Left mouse button, if you hold it down it needs to rotate, but It specifically rotates around the camera, not the player. So changing it to something like:

    Code (csharp):
    1.  
    2. transform.RotateAround(player.position, transform.right, -pos.y * turnSpeed);
    3. transform.RotateAround(player.position, Vector3.up, pos.x * turnSpeed);
    4.  
    5.  
    This will rotate your camera around the player's location, rather than where the camera is.

    panning is pretty much a no no, if you want to keep the camera fixed on the player. So the whole panning thing should not work with that setup.

    zooming is quite a bit different as well. Instead of moving the camera, we need to simply move a variable (float) that will control that zoom factor. For this, you will need a maximum and minimum zoom.

    Code (csharp):
    1.  
    2. Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
    3.  
    4. zoomDistance += -pos.y * zoomRate;
    5. zoomDistance = Mathf.Clamp(zoomDistance, 1, 20);
    6.  
    With that, you then need to re position your camera on the LateUpdate
    Code (csharp):
    1.  
    2. void LateUpdate(){
    3. transform.position = player.position;
    4. transform.Translate(Vector3.back * zoomDistance, Space.Self);
    5. }
    6.  
    Of course, I didn't test any of this, but the theory is sound.

    Additions:

    You should consider using euler angles instead of rotation. With this, you could use angular limits for the euler. (like -60 to 60 degrees) This prevents the player from becoming disoriented.
     
  4. DanielX95

    DanielX95

    Joined:
    Apr 25, 2017
    Posts:
    24
    Thank you so much bigmisterb! The rotation around the player works properly! Just one question: Where should i put these line of codes?

    Code (CSharp):
    1. Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - mouseOrigin);
    2.     zoomDistance += -pos.y * zoomRate;
    3.     zoomDistance = Mathf.Clamp(zoomDistance, 1, 20);
    4.  
    Best regards.
     
  5. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    That would be in place of the isZooming part. You would of course have to add the zoomDistance variable at the top with a default value. (say 5)
     
  6. DanielX95

    DanielX95

    Joined:
    Apr 25, 2017
    Posts:
    24
    Thanks, it works properly. Now, for making the camera follows the player i used this second script:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class FollowPlayer : MonoBehaviour {
    6.  
    7.     public GameObject player;
    8.     private Vector3 cameraLocation;
    9.     // Use this for initialization
    10.     void Start () {
    11.         cameraLocation = transform.position - player.transform.position;
    12.     }
    13.  
    14.     // Update is called once per frame
    15.     void Update () {
    16.         transform.position = player.transform.position + cameraLocation;
    17.     }
    18. }
    19.  
    But if i add this second script too, the camera follows the player, but it does not rotate around the player well. How can i make follows the player well?