Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Orbit camera with keyboard

Discussion in 'Scripting' started by Corva-Nocta, Jan 19, 2020.

  1. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    I am having a surprisingly hard time finding scripts/tutorials online allowing my camera to orbit my player using only the keyboard keys. There are tons for mouse orbit, but surprisingly few for keyboard. Anyway, I want to be able to use wasd or arrow keys to make the camera spin around my player, but always looking at the player. The always looking part I already have, but the rotating is giving me trouble.

    One of the major complications is that I am adding this functionality onto another script in an asset I purchased, so some parts are pretty set in stone (its a multiplayer thing so I don't want to go altering too much)

    I tried this code I found:
    Code (csharp):
    1.  
    2. if (target)
    3.             {
    4.                 x -= Input.GetAxis("Horizontal") * xSpeed * 0.02f;
    5.                 y += Input.GetAxis("Vertical") * ySpeed * 0.02f;
    6.  
    7.                 y = ClampAngle(y, yMinLimit, yMaxLimit);
    8.  
    9.                 distanceCam -= Input.GetAxis("Fire1") * zoomSpd * 0.02f;
    10.                 distanceCam += Input.GetAxis("Fire2") * zoomSpd * 0.02f;
    11.  
    12.                 Quaternion rotation = Quaternion.Euler(y, x, 0.0f);
    13.  
    14.                 Vector3 position = rotation * new Vector3(0.0f, 0.0f, 0.0f) + target.position;
    15.  
    16.                 transform.rotation = rotation;
    17.                 transform.position = position;
    18.             }
    19.  
    20. public static float ClampAngle(float angle, float min, float max)
    21.         {
    22.             if (angle < -360.0f)
    23.             {
    24.                 angle += 360.0f;
    25.             }
    26.             if (angle > 360.0f)
    27.             {
    28.                 angle -= 360.0f;
    29.             }
    30.             return Mathf.Clamp(angle, min, max);
    31.         }
    This kind of works, except it sets the camera to the origin point of my player. It will look around, but it emulates mouse look, not camera rotation. Clearly I am looking in the wrong place so any help from anyone would be greatly appreciated!
     
  2. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Here is the premade code that I am trying to work around:
    Code (csharp):
    1.  
    2. protected void UpdateCamera()
    3.         {
    4.             Camera camera = Camera.main;
    5.  
    6.             // Calculate the current rotation angles
    7.             float wantedHeight = target.position.y + height;
    8.             float currentHeight = camera.transform.position.y;
    9.  
    10.             // Damp the rotation around the y-axis
    11.             // Damp the height
    12.             //currentHeight = Mathf.Lerp (currentHeight, wantedHeight, heightDamping * Time.deltaTime);
    13.             currentHeight = wantedHeight;
    14.  
    15.             // Convert the angle into a rotation
    16.             // Set the position of the camera on the x-z plane to:
    17.             // distance meters behind the target
    18.             camera.transform.position = target.position;
    19.             camera.transform.position -= cameraRotation * distance;
    20.  
    21.             // Set the height of the camera
    22.             camera.transform.position = new Vector3(camera.transform.position.x, currentHeight, camera.transform.position.z);
    23.  
    24.             // Always look at the target
    25.             camera.transform.LookAt(target);
    26. }
    I tried to add in a simple RotateAround at the end after camera.transform.LookAt, something like thiss:
    Code (csharp):
    1.  
    2. if (Input.GetAxis("Horizontal") > 0.0f)
    3.             {
    4.                 transform.RotateAround(target.position, Vector3.up, 30 * Time.deltaTime);
    5.             }
    which just barely works. Now when I press the buttons the camera moves like half a degree for a moment, then stops. I can move it back just slightly. I think that batch of code is fighting with another batch of code, but I'm not sure which ones.
     
  3. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    I think I'm making progress. I moved this part:
    Code (csharp):
    1.  
    2. [LIST=1]
    3. [*]camera.transform.position = target.position;
    4. [*]            camera.transform.position -= cameraRotation * distance;
    [/LIST]
    to the Start() function and now the camera rotates! Unfortunately, it only rotates in one direction, and still moves a little after I stop pressing. So still a bit to figure out. Any help at all would be great!

    [EDIT] so a new small issue has come up. Now with camera will rotate in one direction but it does not follow the player. apparently setting the position within the update helps it move with the player. back to square 1 I suppose
     
    Last edited: Jan 19, 2020
  4. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Simplified the existing code a bit to help understand it.
    Code (csharp):
    1.  
    2. Camera camera = Camera.main;
    3.  
    4.             // Set the position of the camera on the x-z plane to:
    5.             // distance meters behind the target
    6.             camera.transform.position = target.position;
    7.             camera.transform.position -= cameraRotation * distance;
    8.  
    9.             // Set the height of the camera
    10.             camera.transform.position = new Vector3(camera.transform.position.x, target.position.y + height, camera.transform.position.z);
    11.  
    12.             // Always look at the target
    13.             camera.transform.LookAt(target);
    14.  
    15.             if (Input.GetAxis("Horizontal") > 0.0f)
    16.             {
    17.                 camera.transform.RotateAround(target.position, Vector3.up, 30 * Time.deltaTime);
    18.             }
    So now the code is a bit more readable. Still having the issue where the camera will only barely move. I think setting the transform.position to the target.position every time this runs is messing with that. But if I move that to the Start() function like I did earlier, the camera does not move with the player. So I am not really sure what to do
     
  5. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    I finally got it working, for the most part. Went in a slightly different direction and did this:
    Code (csharp):
    1.  
    2. Camera camera = Camera.main;
    3.             camera.transform.position = new Vector3(target.position.x + cameraOffset.x, target.position.y + height, target.position.z + cameraOffset.z);
    4.  
    5.             // Always look at the target
    6.             camera.transform.LookAt(target);
    7.  
    8.             if (Input.GetAxis("Horizontal") > 0.0f)
    9.             {
    10.                 camera.transform.RotateAround(target.position, Vector3.up, 30 * Time.deltaTime);
    11.                 cameraOffset = transform.position - target.transform.position;
    12.             }
    This seems to work for the most part. Will need to adjust some parameters but the basics are all there. Last part I need is the camera is only able to move in one direction, so I am not sure how to set it up so when I press the left arrow the camera moves to the left, and the right arrow moves to the right.
     
  6. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Alright I got the left/right rotation to work

    Code (csharp):
    1.  
    2. Camera camera = Camera.main;
    3.             camera.transform.position = new Vector3(target.position.x + cameraOffset.x, target.position.y + height, target.position.z + cameraOffset.z);
    4.  
    5.             // Always look at the target
    6.             camera.transform.LookAt(target);
    7.  
    8.             if (Input.GetAxis("Horizontal") > 0.0f || Input.GetAxis("Horizontal") < 0.0f)
    9.             {
    10.                 camera.transform.RotateAround(target.position, -Vector3.up * Input.GetAxis("Horizontal"), 30 * Time.deltaTime);
    11.                 cameraOffset = transform.position - target.transform.position;
    12.             }
    so next is working with the zoom, and the up/down