Search Unity

RTS Camera script

Discussion in 'Scripting' started by arashikami, Dec 27, 2010.

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

    arashikami

    Joined:
    Nov 8, 2010
    Posts:
    13
    I am working on a non-game mapping project and I have been looking for help in scripting the main camera to function like those in RTS games like C&C, Age of Empires, ETC. I have been looking for a good tutorial or guide on the subject. Any help or direction would be greatly appreciated.

    thanks,
    Rob
     
    mohe62541 likes this.
  2. Feyhu

    Feyhu

    Joined:
    Sep 14, 2010
    Posts:
    211
    more specific? you could use the arrow keys to move, and the outside of the screen to move also when the mouse is over it.
     
  3. arashikami

    arashikami

    Joined:
    Nov 8, 2010
    Posts:
    13
    The camera should be able to pan with the arrow keys, but also be able to rotate around a selected object or the map itself.
     
    Last edited: Dec 27, 2010
  4. Feyhu

    Feyhu

    Joined:
    Sep 14, 2010
    Posts:
    211
    the pan should be using translate. more specific about the rotating part?
     
  5. iEpinephrine

    iEpinephrine

    Joined:
    Dec 28, 2010
    Posts:
    1
    I'm afraid I don't know any good tutorials but I worked out how to make one by looking up GetAxis in the Scripting Reference.
    Create a GameObject in the Hierarchy viewer
    Attach script like this to GameObject

    Attach Camera to GameObject at position 0,0,0, rotation 50,0,0
    (NOTE: this means the camera will rotate around the bottom of the screen. If you want it to rotate around the center of the screen offset it back from the GameObject slightly. I think.. not sure if that's a great solution but it should work...I think)

    I'm afraid I can't think off the top of my head of a way to rotate around selected object...Do RTS cameras allow that? I haven't played one in a long time, but it sounds like it would get a bit weird if you select a unit, panned away then tried to rotate the screen, still with the unit as the focal point.

    Edit: Btw I came onto the forum with my own question about making an RTS camera and in the process of answering yours I realised a solution to my own. Thanks! :)
     
    Last edited: Dec 28, 2010
  6. profcwalker

    profcwalker

    Joined:
    May 3, 2009
    Posts:
    243
  7. arashikami

    arashikami

    Joined:
    Nov 8, 2010
    Posts:
    13
    Sorry about the delay in replying. I have downloaded the Pathfinder Project from arongranberg.com and looked at the camera script for it as well as played around with it. It is moving in the right direction, but I think the controls need to be simplified a bit more since the main user for the project I am working on isn't a gamer.
     
    B-Collins likes this.
  8. puppeteer

    puppeteer

    Joined:
    Sep 15, 2010
    Posts:
    1,282
    Here's a simple camera script, which is part of a larger RTS game starter kit I'm working on.

    Code (csharp):
    1. var ScrollSpeed:float = 15;
    2. var ScrollEdge:float = 0.01;
    3.  
    4. private var HorizontalScroll:int = 1;
    5. private var VerticalScroll:int = 1;
    6. private var DiagonalScroll:int = 1;
    7.  
    8. var PanSpeed:float = 10;
    9.  
    10. var ZoomRange:Vector2 = Vector2(-5,5);
    11. var CurrentZoom:float = 0;
    12. var ZoomZpeed:float = 1;
    13. var ZoomRotation:float = 1;
    14.  
    15. private var InitPos:Vector3;
    16. private var InitRotation:Vector3;
    17.  
    18.  
    19.  
    20. function Start()
    21. {
    22.     //Instantiate(Arrow, Vector3.zero, Quaternion.identity);
    23.    
    24.     InitPos = transform.position;
    25.     InitRotation = transform.eulerAngles;
    26.    
    27. }
    28.  
    29. function Update ()
    30. {
    31.     //PAN
    32.     if ( Input.GetKey("mouse 2") )
    33.     {
    34.         //(Input.mousePosition.x - Screen.width * 0.5)/(Screen.width * 0.5)
    35.        
    36.         transform.Translate(Vector3.right * Time.deltaTime * PanSpeed * (Input.mousePosition.x - Screen.width * 0.5)/(Screen.width * 0.5), Space.World);
    37.         transform.Translate(Vector3.forward * Time.deltaTime * PanSpeed * (Input.mousePosition.y - Screen.height * 0.5)/(Screen.height * 0.5), Space.World);
    38.  
    39.     }
    40.     else
    41.     {
    42.         if ( Input.GetKey("d") || Input.mousePosition.x >= Screen.width * (1 - ScrollEdge) )
    43.         {
    44.             transform.Translate(Vector3.right * Time.deltaTime * ScrollSpeed, Space.World);
    45.         }
    46.         else if ( Input.GetKey("a") || Input.mousePosition.x <= Screen.width * ScrollEdge )
    47.         {
    48.             transform.Translate(Vector3.right * Time.deltaTime * -ScrollSpeed, Space.World);
    49.         }
    50.        
    51.         if ( Input.GetKey("w") || Input.mousePosition.y >= Screen.height * (1 - ScrollEdge) )
    52.         {
    53.             transform.Translate(Vector3.forward * Time.deltaTime * ScrollSpeed, Space.World);
    54.         }
    55.         else if ( Input.GetKey("s") || Input.mousePosition.y <= Screen.height * ScrollEdge )
    56.         {
    57.             transform.Translate(Vector3.forward * Time.deltaTime * -ScrollSpeed, Space.World);
    58.         }
    59.     }
    60.    
    61. //ZOOM IN/OUT
    62.    
    63.     CurrentZoom -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * 1000 * ZoomZpeed;
    64.    
    65.     CurrentZoom = Mathf.Clamp(CurrentZoom,ZoomRange.x,ZoomRange.y);
    66.    
    67.     transform.position.y -= (transform.position.y - (InitPos.y + CurrentZoom)) * 0.1;
    68.     transform.eulerAngles.x -= (transform.eulerAngles.x - (InitRotation.x + CurrentZoom * ZoomRotation)) * 0.1;
    69.    
    70. }
    - If you roll the mouse wheel the camera will zoom in/out.
    - If you go to the edges of the screen the camera will scroll.
    - The camera will also scroll if you press W/A/S/D.
    - If you hold the Middle mouse button and move you will pan across the screen.

    Attach this to a camera ( The camera I had was rotated to 60 in the X axis ). You can tweak the values from the inspector.

    Tell me how it goes for you.
     
  9. arashikami

    arashikami

    Joined:
    Nov 8, 2010
    Posts:
    13
    Sorry about the delay. I tested out the script you posted and it works for the most part. The only problems with the script is a lack of rotation on the Y axis and the camera tests to act very strange when it goes below the ground plane. This is corrected by changing the Zoom Range x variable to 0. I will work with the script some more this week along with our web programmer to see how it works for us overall.

    Thanks,
    Rob


     
  10. arashikami

    arashikami

    Joined:
    Nov 8, 2010
    Posts:
    13
    I have been working with the script kindly provided by Puppeteer with the focus on adding a rotation component to the camera using the left mouse button plus the control key. However, since I am only a noob in programming, I seem to be having a problem figuring out the right script/input to get the camera to rotate on the Y axis. Here is the code I have added to the camera script:

    Code (csharp):
    1. var ScrollSpeed:float = 15;
    2. var ScrollEdge:float = 0.01;
    3.  
    4. private var HorizontalScroll:int = 1;
    5. private var VerticalScroll:int = 1;
    6. private var DiagonalScroll:int = 1;
    7.  
    8. var PanSpeed:float = 10;
    9.  
    10. var ZoomRange:Vector2 = Vector2(0,10);
    11. var CurrentZoom:float = 0;
    12. var ZoomZpeed:float = 1;
    13. var ZoomRotation:float = 1;
    14.  
    15. //camera rotation on Y axis
    16. var RotationSpeed : float = 1;
    17. var CamRotY : Vector3;
    18.  
    19. private var InitPos:Vector3;
    20. private var InitRotation:Vector3;
    21.  
    22.  
    23.  
    24. function Start()
    25. {
    26.     //Instantiate(Arrow, Vector3.zero, Quaternion.identity);
    27.    
    28.     InitPos = transform.position;
    29.     InitRotation = transform.eulerAngles;
    30.    
    31. }
    32.  
    33. function Update ()
    34. {
    35.     //PAN
    36.     if ( Input.GetKey("mouse 2") )
    37.     {
    38.         //(Input.mousePosition.x - Screen.width * 0.5)/(Screen.width * 0.5)
    39.        
    40.         transform.Translate(Vector3.right * Time.deltaTime * PanSpeed * (Input.mousePosition.x - Screen.width * 0.5)/(Screen.width * 0.5), Space.World);
    41.         transform.Translate(Vector3.forward * Time.deltaTime * PanSpeed * (Input.mousePosition.y - Screen.height * 0.5)/(Screen.height * 0.5), Space.World);
    42.  
    43.     }
    44.     else
    45.     {
    46.         if ( Input.GetKey("d") || Input.mousePosition.x >= Screen.width * (1 - ScrollEdge) )
    47.         {
    48.             transform.Translate(Vector3.right * Time.deltaTime * ScrollSpeed, Space.World);
    49.         }
    50.         else if ( Input.GetKey("a") || Input.mousePosition.x <= Screen.width * ScrollEdge )
    51.         {
    52.             transform.Translate(Vector3.right * Time.deltaTime * -ScrollSpeed, Space.World);
    53.         }
    54.        
    55.         if ( Input.GetKey("w") || Input.mousePosition.y >= Screen.height * (1 - ScrollEdge) )
    56.         {
    57.             transform.Translate(Vector3.forward * Time.deltaTime * ScrollSpeed, Space.World);
    58.         }
    59.         else if ( Input.GetKey("s") || Input.mousePosition.y <= Screen.height * ScrollEdge )
    60.         {
    61.             transform.Translate(Vector3.forward * Time.deltaTime * -ScrollSpeed, Space.World);
    62.         }
    63.     }
    64.    
    65. //ZOOM IN/OUT
    66.    
    67.     CurrentZoom -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * 1000 * ZoomZpeed;
    68.    
    69.     CurrentZoom = Mathf.Clamp(CurrentZoom,ZoomRange.x,ZoomRange.y);
    70.    
    71.     transform.position.y -= (transform.position.y - (InitPos.y + CurrentZoom)) * 0.1;
    72.     transform.eulerAngles.x -= (transform.eulerAngles.x - (InitRotation.x + CurrentZoom * ZoomRotation)) * 0.1;
    73.  
    74. //ROTATION
    75.     //Use Mouse 1 + Ctrl key to rotate the camera around the Y axis
    76.     if (Input.GetAxis ("mouse 1")  Input.GetKey ("CTRL")){
    77.         transform.Rotate (CamRotY, RotationSpeed * Time.deltaTime, Space.World);
    78.     }
    79. }
    Any ideas or help would be greatly appreciated.
     
  11. matis1989

    matis1989

    Joined:
    Mar 23, 2011
    Posts:
    162
    Hi,
    great work BUT I have just 2d top down game camera i rotated 90 on X and is orthographic. How can I set zoom in/out just on one axis(+/- Y axis)?
    Thank you for help.

     
  12. robomanus

    robomanus

    Joined:
    Feb 13, 2014
    Posts:
    1
    Now if we want to add rotation - to the left pressing "Q" button and to the right pressing "E" button adding to the code something like this:

    Code (csharp):
    1. ........
    2. else if ( Input.GetKey("q"))
    3.  
    4.         {
    5.  
    6.             transform.Rotate(Vector3.up * Time.deltaTime * -ScrollSpeed, Space.World);
    7.  
    8.         }
    9.        
    10.         else if ( Input.GetKey("e"))
    11.  
    12.         {
    13.  
    14.             transform.Rotate(Vector3.down * Time.deltaTime * -ScrollSpeed, Space.World);
    15.  
    16.         }
    17. ...................
    18.  
    We have now rotation but when we move by W/A/S/D it will follow the axis original cordinates not the actual view coordinates:

    If I rotate the view to the right at 90 degrees by pressing 'E' button and then press 'W' button, the camera will move to the left now!! and not forward accordingly to my view...

    So I want to rotate my camera
    Code (csharp):
    1. transform.Rotate(Vector3.up * Time.deltaTime * -ScrollSpeed, Space.World);
    and move accordingly actual view..(like in Wasteland2)
    Exactly what I mean

    Some suggestions???
     
    Last edited: Feb 13, 2014
  13. chakie

    chakie

    Joined:
    Jul 31, 2011
    Posts:
    14
    I took the Javascript version and adapted it a bit for my needs and converted it to C#. It uses the added Q/E for rotation, makes the panning work when the camera is rotated. It also changes so that the camera rotates near the left/right edges instead of panning. For my needs the camera needs to zoom out much higher, so the zoomRange is larger. Also added a max zoom angle so that the camera doesn't flip around when it looks straight down.


    Code (csharp):
    1. public class RTSCamera : MonoBehaviour {
    2.  
    3.    
    4.     public float ScrollSpeed = 15;
    5.    
    6.     public float ScrollEdge = 0.1f;
    7.    
    8.     public float PanSpeed = 10;
    9.    
    10.     public Vector2 zoomRange = new Vector2( -10, 100 );
    11.    
    12.     public float CurrentZoom = 0;
    13.    
    14.     public float ZoomZpeed = 1;
    15.    
    16.     public float ZoomRotation = 1;
    17.  
    18.     public Vector2 zoomAngleRange = new Vector2( 20, 70 );
    19.  
    20.     public float rotateSpeed = 10;
    21.  
    22.     private Vector3 initialPosition;
    23.    
    24.     private Vector3 initialRotation;
    25.    
    26.  
    27.     void Start () {
    28.         initialPosition = transform.position;      
    29.         initialRotation = transform.eulerAngles;
    30.     }
    31.    
    32.  
    33.     void Update () {
    34.         // panning     
    35.         if ( Input.GetMouseButton( 0 ) ) {
    36.             transform.Translate(Vector3.right * Time.deltaTime * PanSpeed * (Input.mousePosition.x - Screen.width * 0.5f) / (Screen.width * 0.5f), Space.World);
    37.             transform.Translate(Vector3.forward * Time.deltaTime * PanSpeed * (Input.mousePosition.y - Screen.height * 0.5f) / (Screen.height * 0.5f), Space.World);
    38.         }
    39.        
    40.         else {
    41.             if ( Input.GetKey("d") ) {             
    42.                 transform.Translate(Vector3.right * Time.deltaTime * PanSpeed, Space.Self );   
    43.             }
    44.             else if ( Input.GetKey("a") ) {            
    45.                 transform.Translate(Vector3.right * Time.deltaTime * -PanSpeed, Space.Self );              
    46.             }
    47.  
    48.             if ( Input.GetKey("w") || Input.mousePosition.y >= Screen.height * (1 - ScrollEdge) ) {            
    49.                 transform.Translate(Vector3.forward * Time.deltaTime * PanSpeed, Space.Self );             
    50.             }
    51.             else if ( Input.GetKey("s") || Input.mousePosition.y <= Screen.height * ScrollEdge ) {         
    52.                 transform.Translate(Vector3.forward * Time.deltaTime * -PanSpeed, Space.Self );            
    53.             }  
    54.  
    55.             if ( Input.GetKey("q") || Input.mousePosition.x <= Screen.width * ScrollEdge ) {
    56.                 transform.Rotate(Vector3.up * Time.deltaTime * -rotateSpeed, Space.World);
    57.             }
    58.             else if ( Input.GetKey("e") || Input.mousePosition.x >= Screen.width * (1 - ScrollEdge) ) {
    59.                 transform.Rotate(Vector3.up * Time.deltaTime * rotateSpeed, Space.World);
    60.             }
    61.         }
    62.  
    63.         // zoom in/out
    64.         CurrentZoom -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * 1000 * ZoomZpeed;
    65.  
    66.         CurrentZoom = Mathf.Clamp( CurrentZoom, zoomRange.x, zoomRange.y );
    67.  
    68.         transform.position = new Vector3( transform.position.x, transform.position.y - (transform.position.y - (initialPosition.y + CurrentZoom)) * 0.1f, transform.position.z );
    69.  
    70.         float x = transform.eulerAngles.x - (transform.eulerAngles.x - (initialRotation.x + CurrentZoom * ZoomRotation)) * 0.1f;
    71.         x = Mathf.Clamp( x, zoomAngleRange.x, zoomAngleRange.y );
    72.  
    73.         transform.eulerAngles = new Vector3( x, transform.eulerAngles.y, transform.eulerAngles.z );
    74.     }
    75. }
    76.  
     
    silverpalm39 likes this.
  14. Deadlycow

    Deadlycow

    Joined:
    Dec 5, 2013
    Posts:
    1
    Thx saved me alot of time (shame unity don't have RTS camera by default script)
     
  15. roger_lew

    roger_lew

    Joined:
    Apr 21, 2015
    Posts:
    13
    Here's another one that more closely emulates the scene view RTS
    - has a quadratic panspeed curve.
    - 'a' and 'd' translate instead of rotate the camera
    - scrollwheel zoom affects the camera's field of view instead of the the camera's translation

    Code (csharp):
    1.  
    2. /*
    3. * Copyright (c) 2014, Roger Lew (rogerlew.gmail.com)
    4. * Date: 5/12/2015
    5. * License: BSD (3-clause license)
    6. *
    7. * The project described was supported by NSF award number IIA-1301792
    8. * from the NSF Idaho EPSCoR Program and by the National Science Foundation.
    9. *
    10. */
    11.  
    12. using UnityEngine;
    13. using System.Collections;
    14.  
    15. namespace VTL.RTSCamera
    16. {
    17.     public class RTSCamera : MonoBehaviour
    18.     {
    19.         // WASDQE Panning
    20.         public float minPanSpeed = 0.1f;    // Starting panning speed
    21.         public float maxPanSpeed = 1000f;   // Max panning speed
    22.         public float panTimeConstant = 20f; // Time to reach max panning speed
    23.  
    24.         // Mouse right-down rotation
    25.         public float rotateSpeed = 10; // mouse down rotation speed about x and y axes
    26.         public float zoomSpeed = 2;    // zoom speed
    27.  
    28.         float panT = 0;
    29.         float panSpeed = 10;
    30.         Vector3 panTranslation;
    31.         bool wKeyDown = false;
    32.         bool aKeyDown = false;
    33.         bool sKeyDown = false;
    34.         bool dKeyDown = false;
    35.         bool qKeyDown = false;
    36.         bool eKeyDown = false;
    37.      
    38.         Vector3 lastMousePosition;
    39.         new Camera camera;
    40.  
    41.         void Start()
    42.         {
    43.             camera = GetComponent<Camera>();
    44.         }
    45.  
    46.         void Update()
    47.         {
    48.             //
    49.             // WASDQE Panning
    50.  
    51.             // read key inputs
    52.             wKeyDown = Input.GetKey(KeyCode.W);
    53.             aKeyDown = Input.GetKey(KeyCode.A);
    54.             sKeyDown = Input.GetKey(KeyCode.S);
    55.             dKeyDown = Input.GetKey(KeyCode.D);
    56.             qKeyDown = Input.GetKey(KeyCode.Q);
    57.             eKeyDown = Input.GetKey(KeyCode.E);
    58.  
    59.             // determine panTranslation
    60.             panTranslation = Vector3.zero;
    61.             if (dKeyDown && !aKeyDown)
    62.                 panTranslation += Vector3.right * Time.deltaTime * panSpeed;
    63.             else if (aKeyDown && !dKeyDown)
    64.                 panTranslation += Vector3.left * Time.deltaTime * panSpeed;
    65.  
    66.             if (wKeyDown && !sKeyDown)
    67.                 panTranslation += Vector3.forward * Time.deltaTime * panSpeed;
    68.             else if (sKeyDown && !wKeyDown)
    69.                 panTranslation += Vector3.back * Time.deltaTime * panSpeed;
    70.  
    71.             if (qKeyDown && !eKeyDown)
    72.                 panTranslation += Vector3.down * Time.deltaTime * panSpeed;
    73.             else if (eKeyDown && !qKeyDown)
    74.                 panTranslation += Vector3.up * Time.deltaTime * panSpeed;
    75.             transform.Translate(panTranslation, Space.Self);
    76.  
    77.             // Update panSpeed
    78.             if (wKeyDown || aKeyDown || sKeyDown ||
    79.                 dKeyDown || qKeyDown || eKeyDown)
    80.             {
    81.                 panT += Time.deltaTime / panTimeConstant;
    82.                 panSpeed = Mathf.Lerp(minPanSpeed, maxPanSpeed, panT * panT);
    83.             }
    84.             else
    85.             {
    86.                 panT = 0;
    87.                 panSpeed = minPanSpeed;
    88.             }
    89.  
    90.             //
    91.             // Mouse Rotation
    92.             if (Input.GetMouseButton(1))
    93.             {
    94.                 // if the game window is separate from the editor window and the editor
    95.                 // window is active then you go to right-click on the game window the
    96.                 // rotation jumps if  we don't ignore the mouseDelta for that frame.
    97.                 Vector3 mouseDelta;
    98.                 if (lastMousePosition.x >= 0 &&
    99.                     lastMousePosition.y >= 0 &&
    100.                     lastMousePosition.x <= Screen.width &&
    101.                     lastMousePosition.y <= Screen.height)
    102.                     mouseDelta = Input.mousePosition - lastMousePosition;
    103.                 else
    104.                     mouseDelta = Vector3.zero;
    105.  
    106.                 var rotation = Vector3.up * Time.deltaTime * rotateSpeed * mouseDelta.x;
    107.                 rotation += Vector3.left * Time.deltaTime * rotateSpeed * mouseDelta.y;
    108.                 transform.Rotate(rotation, Space.Self);
    109.  
    110.                 // Make sure z rotation stays locked
    111.                 rotation = transform.rotation.eulerAngles;
    112.                 rotation.z = 0;
    113.                 transform.rotation = Quaternion.Euler(rotation);
    114.             }
    115.  
    116.             lastMousePosition = Input.mousePosition;
    117.  
    118.             //
    119.             // Mouse Zoom
    120.             camera.fieldOfView -= Input.mouseScrollDelta.y * zoomSpeed;
    121.         }
    122.     }
    123. }
    124.  
     
    Last edited: May 12, 2015
    Over-Dreaming likes this.
  16. mrgarcialuigi

    mrgarcialuigi

    Joined:
    Feb 11, 2015
    Posts:
    12
    This is a RTS camera I'have created some time ago. Maybe it can help someone.
    [Post]
    [Github link]
     
  17. MV10

    MV10

    Joined:
    Nov 6, 2015
    Posts:
    1,889
    My requirements were probably a little unusual but since I started from roger_lew's code, I figured I'd share the results. In my case movement is over a large circular area (2000 unit diameter), so I clamp the camera distance from the origin and the movement speeds are cranked up quite a bit. Altitude is fixed (y=400, again, very large area) so movement is purely in XZ. The game is completely mouse-controlled, so the control scheme is a bit different but it feels natural -- left button moves forward, right button moves backwards. You can rotate while moving. Press both buttons to rotate without movement. I also restrict the FOV zoom to min/max.

    I know none of this is standard RTS but maybe some of the other features will be useful to somebody.

    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class CameraMovement : MonoBehaviour
    4. {
    5.     // Left mouse button: Move forward with rotation
    6.     // Right mouse button: Move backward with rotation
    7.     // Both buttons: Rotate without movement
    8.  
    9.     // Limits
    10.     float startFOV = 60;
    11.     float minFOV = 15f;
    12.     float maxFOV = 90f;
    13.     float maxDistance = 900f; // from 0,0,0
    14.  
    15.     // Movement (left/right mouse)
    16.     float minMoveSpeed = 250f;
    17.     float maxMoveSpeed = 700f;
    18.     float moveRampTime = 5f;
    19.  
    20.     // Rotation (both mouse buttons)
    21.     float rotateSpeed = 6f;
    22.  
    23.     float zoomSpeed = 3f;
    24.  
    25.     Camera cam;
    26.     float movementTime = 0;
    27.     float movementSpeed = 10;
    28.     Vector3 lastMousePosition;
    29.  
    30.     void Awake()
    31.     {
    32.         cam = GetComponent<Camera>();
    33.         cam.fieldOfView = startFOV;
    34.     }
    35.  
    36.     void LateUpdate()
    37.     {
    38.         bool b0 = Input.GetMouseButton(0);
    39.         bool b1 = Input.GetMouseButton(1);
    40.  
    41.         // Movement (Left: forward, Right: backward)
    42.         Vector3 translate = Vector3.zero;
    43.         if(b0 != b1)
    44.         {
    45.             float direction = (b0) ? 1 : -1;
    46.             translate = transform.forward.normalized * direction * Time.deltaTime * movementSpeed;
    47.             translate.y = 0f;
    48.             translate = Vector3.ClampMagnitude(
    49.                new Vector3(transform.position.x, 0f, transform.position.z) + translate,
    50.                maxDistance);
    51.             translate.y = transform.position.y;
    52.             transform.position = translate;
    53.  
    54.             movementTime += Time.deltaTime / moveRampTime;
    55.             movementSpeed = Mathf.Lerp(minMoveSpeed, maxMoveSpeed, movementTime * movementTime);
    56.         }
    57.         else
    58.         {
    59.             movementTime = 0;
    60.             movementSpeed = minMoveSpeed;
    61.         }
    62.  
    63.         // Rotation (either button)
    64.         if(b0 || b1)
    65.         {
    66.             // if the game window is separate from the editor window and the editor
    67.             // window is active then you go to right-click on the game window the
    68.             // rotation jumps if  we don't ignore the mouseDelta for that frame.
    69.             Vector3 mouseDelta;
    70.             if(lastMousePosition.x >= 0
    71.                 && lastMousePosition.y >= 0
    72.                 && lastMousePosition.x <= Screen.width
    73.                 && lastMousePosition.y <= Screen.height)
    74.                     mouseDelta = Input.mousePosition - lastMousePosition;
    75.             else
    76.                 mouseDelta = Vector3.zero;
    77.  
    78.             Vector3 rotation = Vector3.up * Time.deltaTime * rotateSpeed * mouseDelta.x;
    79.             rotation += Vector3.left * Time.deltaTime * rotateSpeed * mouseDelta.y;
    80.             transform.Rotate(rotation, Space.Self);
    81.  
    82.             // Make sure z rotation stays locked
    83.             rotation = transform.rotation.eulerAngles;
    84.             rotation.z = 0;
    85.             transform.rotation = Quaternion.Euler(rotation);
    86.         }
    87.         lastMousePosition = Input.mousePosition;
    88.  
    89.         // Zoom (wheel)
    90.         cam.fieldOfView = Mathf.Clamp(cam.fieldOfView - Input.mouseScrollDelta.y * zoomSpeed, minFOV, maxFOV);
    91.     }
    92. }
     
  18. Skyfall106

    Skyfall106

    Joined:
    Mar 5, 2017
    Posts:
    132
    Thanks this REALLY Helped the development of my game!​
     
  19. mj2carlsbad

    mj2carlsbad

    Joined:
    May 28, 2019
    Posts:
    1
    [EDIT] : I fixed the camera so that it doesn't rely on a frame by frame multiplier (I found it was slowing down the movement of the camera as usage got heavy. It now simply works by making the current rotation the same value as the y-position value, within the bounds you set via the editor. You can of course make it (transform.position.y +/- yourValue) if you think a little offset might look good.

    I pasted the new code below, and I'll leave the old file for reference. The one you want is CameraControlFixed.cs

    The only bug is if your panSpeed is so ridiculously high that your camera goes beyond the bounds before a frame can even check it.

    --------------------------------------------------------------------------------------------------------------

    For anybody that's still looking in here, I made this simple Camera Script with limitations and rotation as you go in and out using 'R' and 'F'.
    Pretty much all the necessary fields can be set from within the editor as you play around with it in runtime to figure out what looks good

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class CameraControlFixed : MonoBehaviour
    5. {
    6.  
    7.     public float panSpeed = 30f;
    8.     public float windowEdgeBorder = 10f;
    9.     private float cameraYRot;
    10.     private float cameraZRot;
    11.  
    12.     [Header("CameraLimits")]
    13.     public float leftLimit = 0f;
    14.     public float rightLimit = 70f;
    15.     public float upLimit = 65f;
    16.     public float downLimit = -4f;
    17.     public float zoomInLimit = 8f;
    18.     public float zoomOutLimit = 55f;
    19.     public float xRotationLowerLimit = 10f;
    20.     public float xRotationUpperLimit = 90f;
    21.  
    22.     void Start() {
    23.         cameraYRot = transform.rotation.y;
    24.         cameraZRot = transform.rotation.z;
    25.     }
    26.  
    27.  
    28.     // Update is called once per frame
    29.     void Update()
    30.     {
    31.         float mouseY = Input.mousePosition.y;
    32.         float mouseX = Input.mousePosition.x;
    33.  
    34.         /*
    35.             Camera controls in this next condition after we
    36.                 check that the mouse is within the window
    37.          */
    38.         if (mouseX >= 0 && mouseX <= Screen.width &&
    39.             mouseY >= 0 && mouseY <= Screen.height)
    40.         {
    41.             /*
    42.                 Below we are checking that
    43.                 A.) a specific key is pressed
    44.                 B.) in some cases (left, right, back, forward) that the mouse is within the
    45.                         edges of the screen via the border and Screen attributes
    46.                 C.) the camera's current position is not past the set limits
    47.  
    48.                 Then we Translate that camera toward a certain direction relative to the
    49.                     World Space
    50.              */
    51.  
    52.  
    53.  
    54.             // up with 'w'
    55.             if ((Input.GetKey("w") || mouseY >= Screen.height - windowEdgeBorder) &&
    56.                 transform.position.z < upLimit) {
    57.                 transform.Translate(Vector3.forward * panSpeed * Time.deltaTime,
    58.                                     Space.World);
    59.             }
    60.  
    61.             // left with 'a'
    62.             if ((Input.GetKey("a") || mouseX <= windowEdgeBorder) &&
    63.                 transform.position.x > leftLimit) {
    64.                 transform.Translate(Vector3.left * panSpeed * Time.deltaTime,
    65.                                     Space.World);
    66.             }
    67.        
    68.             // down with 's'
    69.             if ((Input.GetKey("s") || mouseY <= windowEdgeBorder) &&
    70.                 transform.position.z > downLimit) {
    71.                 transform.Translate(Vector3.back * panSpeed * Time.deltaTime,
    72.                                     Space.World);
    73.             }
    74.        
    75.             // right with 'd'
    76.             if ((Input.GetKey("d") || mouseX >= Screen.width - windowEdgeBorder) &&
    77.                 transform.position.x < rightLimit) {
    78.                 transform.Translate(Vector3.right * panSpeed * Time.deltaTime,
    79.                                     Space.World);
    80.             }
    81.        
    82.             // zoom in
    83.             if (Input.GetKey("r") && transform.position.y > zoomInLimit) {
    84.  
    85.                 transform.Translate(Vector3.down * panSpeed * Time.deltaTime, Space.World);
    86.                 //transform.Rotate(-rotationPivotFactor* rotationSpeedPerFrame, 0f, 0f, Space.Self);
    87.                 if (transform.position.y > xRotationLowerLimit && transform.position.y < xRotationUpperLimit)
    88.                     transform.rotation = Quaternion.Euler( transform.position.y, cameraYRot, cameraZRot);
    89.             }
    90.        
    91.             // zoom out
    92.             if (Input.GetKey("f") && transform.position.y < zoomOutLimit) {
    93.                 transform.Translate(Vector3.up * panSpeed * Time.deltaTime, Space.World);
    94.                 //transform.Rotate(rotationPivotFactor* rotationSpeedPerFrame, 0f, 0f, Space.Self);
    95.                 if (transform.position.y > xRotationLowerLimit && transform.position.y < xRotationUpperLimit)
    96.                     transform.rotation = Quaternion.Euler( transform.position.y, cameraYRot, cameraZRot);
    97.             }
    98.         }
    99.     }
    100. }
    101.  
    102.  
    103.  
    [EDIT 2] : Looks like I was missing this too. I had it in my project but forgot to upload. Don't credit me for this though, I forget where I got it... Has to do with Screen Size and how the Camera changes accordingly

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3.  
    4. [ExecuteInEditMode]
    5. [RequireComponent(typeof(Camera))]
    6. public class ScreenSize : MonoBehaviour
    7. {
    8.  
    9.     // Set this to the in-world distance between the left & right edges of your scene.
    10.     public float sceneWidth = 10;
    11.  
    12.     Camera _camera;
    13.     void Start()
    14.     {
    15.         _camera = GetComponent<Camera>();
    16.     }
    17.  
    18.     // Adjust the camera's height so the desired scene width fits in view
    19.     // even if the screen/window size changes dynamically.
    20.     void Update()
    21.     {
    22.         float unitsPerPixel = sceneWidth / Screen.width;
    23.  
    24.         float desiredHalfHeight = 0.5f * unitsPerPixel * Screen.height;
    25.  
    26.         _camera.orthographicSize = desiredHalfHeight;
    27.     }
    28. }



    Still new to 3-d programming, from what I can tell it works consistently, but maybe I'm missing something. Although the camera moves on the Y-Axis with Time.deltaTime, the rotation is based on each frame because I figured it would need a consistent multiplier​
     

    Attached Files:

    Last edited: Jun 6, 2019
    puppeteer likes this.
  20. ShowLagg

    ShowLagg

    Joined:
    Nov 26, 2021
    Posts:
    1
    I made the camera a child of another (empty) gameObject with an offset so that the camera is looking at its parent. I put the cameraScript on the parent. So when the parent turns, the child (the camera) will turn aswell. But instead of the camera turning around its own axis, it turns around the axis of the parent. Thus recreating the RTSCamera style.

    Furthermore, if the camera rotates, the movement axis rotate with it. (so after turning 90 degrees to the left, it will now go forward in the camera's direction (so 90 degrees to the left))

    You do need to make sure that when you move your camera (or actually the camera's parent), the scale is set to the Local scale.
    For example:
    transform.Translate(Vector3.left * panSpeed * Time.deltaTime, Space.Self);

    The Space.Self means that the scale is set to local.
     
  21. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,692
    After 13 years of necro-posting, guess what?

    Camera stuff is STILL pretty tricky... you may wish to consider using Cinemachine from the Unity Package Manager.

    There's even a dedicated forum: https://forum.unity.com/forums/cinemachine.136/
     
Thread Status:
Not open for further replies.