Search Unity

The simplest orbit camera that can be made in C#

Discussion in 'Getting Started' started by rapidrunner, May 22, 2016.

Thread Status:
Not open for further replies.
  1. rapidrunner

    rapidrunner

    Joined:
    Jun 11, 2008
    Posts:
    944
    I am using a pre-made asset, but it is too big and has features that I do not really need.

    I need to be able to rotate the camera with the mouse button pressed, and scroll when hitting the borders with the pointer. I can live without the scrolling part, using the keyboard to move in the 4 directions.
    Last but not least; zoom in and out.

    Would this be enough to make an orbit camera? I am looking for the smallest implementation possible, so I can minimize the codebase and the footprint of the application (less code, less bugs!).

    Since I never wrote a camera from scratch; I am not sure if I am missing something or not. Would be great if Unity would add a prefab in its standard assets, to cover such case :)
     
  2. rapidrunner

    rapidrunner

    Joined:
    Jun 11, 2008
    Posts:
    944
    I think I have something that does what I need.

    The only issue that I have is that the camera, when at an angle (say 25 on X axis), when I move forward, after a rotation; it continue to move to where the "forward" is, instead than the "forward" of the object. To fix this I do a translate using Space.Self.

    The downside is that if I move the camera forward now, it will act like the zoom.

    How do you tell the camera, to move on the X and Z axis, so it act like if the camera is nailed to the ceiling of a room, but at the same time, if there is a rotation, say 90 degree on X, when I go forward , it should follow forward, relative to where the camera is pointing at.

    I am aiming at a standard Orbit camera, exactly like a standard RTS (C&C).
     
  3. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    814
    There's an exact implementation in my book; maybe later I'll be able to post the entire explanation here. In the meantime, the most important part is that you aren't moving the camera directly when you press forward; instead, move the object it is orbiting around. That of couse means there should be an object (possibly an empty gameobject) that the camera is attached to.
     
    rapidrunner, Ryiah and JoeStrout like this.
  4. rapidrunner

    rapidrunner

    Joined:
    Jun 11, 2008
    Posts:
    944
    Thanks; I didn't know that there was a difference between moving the camera itself and when it is the child of another GO.

    I will try in that way and see if I can get something that fit my need; Thanks!
     
  5. rapidrunner

    rapidrunner

    Joined:
    Jun 11, 2008
    Posts:
    944
    So the tip is correct :) creating an empty object, you have to reset to 0 though; in this way when I move forward, it will be parallel to the ground plane.
    Once I set the camera as child, I can change rotation and inclination of the camera viewpoint, and it will move as expected. Thanks!

    This is the whole script, in case someone may find it useful.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class RtsCamera : MonoBehaviour
    4. {
    5.  
    6.     public float speed = 2.0f;                  // movement speed when scrolling on the side of the screen
    7.     public float zoom_speed = 2.0f;             // zoom speed
    8.     public float speed_x = 200.0f;              // Rotation speed
    9.     float rotation_y = 0.0f;                    // variable used for rotation function
    10.     private int edge_threshold = 5;             // area before the end of the screen where scrolling activate
    11.     // limits
    12.     public float scroll_limit_x = 5f;                // how much you can scroll from the center of the scene on the X axis.
    13.     public float scroll_limit_z = 5f;                // how much you can scroll from the center of the screen on the Y axis.
    14.  
    15.  
    16.     void Start()
    17.     {
    18.         // adapt the limits based on the starting position of the camera.
    19.         // in this way, there will always be an equal amount to the limit value
    20.         // independently from where the starting position is.
    21.         if (transform.position.x > 0)
    22.             scroll_limit_x += transform.position.x;
    23.         else
    24.             scroll_limit_x -= transform.position.x;
    25.  
    26.         if (transform.position.z > 0)
    27.             scroll_limit_z += transform.position.z;
    28.         else
    29.             scroll_limit_z -= transform.position.z;
    30.     }
    31.  
    32.     void Update()
    33.     {
    34.         float scrollwheel = Input.GetAxis("Mouse ScrollWheel");
    35.         float mouse_x = Input.mousePosition.x;
    36.         float mouse_y = Input.mousePosition.y;
    37.  
    38.         //zoom with scroll wheel; forward to zoom in, backward to scroll out.
    39.         transform.Translate(0, -scrollwheel * zoom_speed, scrollwheel * zoom_speed, Space.World);
    40.  
    41.         // Orbit function using right mouse button pressed.
    42.         if (Input.GetMouseButton(1))
    43.         {
    44.             rotation_y += Input.GetAxis("Mouse X") * speed_x * Time.deltaTime;
    45.             transform.localEulerAngles = new Vector3(0, rotation_y, 0);
    46.         }
    47.  
    48.         // movement scrolling on the side of the screen; the threshold define how far to the border
    49.         // is the scrolling activating.
    50.         if (mouse_x >= Screen.width - edge_threshold && transform.position.x <= scroll_limit_x)
    51.         {
    52.             transform.Translate((Vector3.right * speed * Time.deltaTime), Space.Self);
    53.         }
    54.         else if (mouse_x < edge_threshold && transform.position.x >= -scroll_limit_x)
    55.         {
    56.             transform.Translate((Vector3.left * speed * Time.deltaTime), Space.Self);
    57.         }
    58.         else if (mouse_y >= Screen.height - edge_threshold && transform.position.z <= scroll_limit_z)
    59.         {
    60.             transform.Translate((Vector3.forward * speed * Time.deltaTime), Space.Self);
    61.         }
    62.         else if (mouse_y < edge_threshold && transform.position.z >= -scroll_limit_z)
    63.         {
    64.             transform.Translate((Vector3.back * speed * Time.deltaTime), Space.Self);
    65.         }
    66.  
    67.     }
    68. }
     
    Last edited: May 23, 2016
    lelo83 and jhocking like this.
Thread Status:
Not open for further replies.