Created
February 28, 2020 20:32
-
-
Save mauro-baptista/78dc887fc1bd20c35fa3424527d8f15b to your computer and use it in GitHub Desktop.
Camera Controller for Strategy Games [Unity]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This code was created by the Youtube channel Game Dev Guide | |
* Please watch this video: https://www.youtube.com/watch?v=rnqF6S7PfFA | |
* | |
* Note: It has a couple of small changes, but it should work as the | |
* code shown on the video. | |
*/ | |
using UnityEngine; | |
public class CameraController : MonoBehaviour | |
{ | |
public Camera cam; | |
public float normalSpeed; | |
public float fastSpeed; | |
private float _movementSpeed; | |
public float movementTime; | |
private Vector3 _newPosition; | |
public float rotationAmount; | |
private Quaternion _newRotation; | |
public Vector3 zoomAmount; | |
private Vector3 _newZoom; | |
private Vector3 _dragStartPosition; | |
private Vector3 _dragCurrentPosition; | |
private Vector3 _rotateStartPosition; | |
private Vector3 _rotateCurrentPosition; | |
// Start is called before the first frame update | |
void Start() | |
{ | |
_newPosition = transform.position; | |
_newRotation = transform.rotation; | |
_newZoom = cam.transform.localPosition; | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
HandleMouseInput(); | |
HandleMovementInput(); | |
} | |
void HandleMouseInput() | |
{ | |
if (Input.mouseScrollDelta.y != 0) | |
{ | |
_newZoom += Input.mouseScrollDelta.y * zoomAmount; | |
} | |
if (Input.GetMouseButtonDown(0)) | |
{ | |
Plane plane = new Plane(Vector3.up, Vector3.zero); | |
Ray ray = cam.ScreenPointToRay(Input.mousePosition); | |
if (plane.Raycast(ray, out float entry)) | |
{ | |
_dragStartPosition = ray.GetPoint(entry); | |
} | |
} | |
if (Input.GetMouseButton(0)) | |
{ | |
Plane plane = new Plane(Vector3.up, Vector3.zero); | |
Ray ray = cam.ScreenPointToRay(Input.mousePosition); | |
if (plane.Raycast(ray, out float entry)) | |
{ | |
_dragCurrentPosition = ray.GetPoint(entry); | |
_newPosition = transform.position + _dragStartPosition - _dragCurrentPosition; | |
} | |
} | |
if (Input.GetMouseButtonDown(2)) | |
{ | |
_rotateStartPosition = Input.mousePosition; | |
} | |
if (Input.GetMouseButton(2)) | |
{ | |
_rotateCurrentPosition = Input.mousePosition; | |
Vector3 difference = _rotateStartPosition - _rotateCurrentPosition; | |
_rotateStartPosition = _rotateCurrentPosition; | |
_newRotation *= Quaternion.Euler(Vector3.down * difference.x / 5f); | |
} | |
} | |
void HandleMovementInput() | |
{ | |
_movementSpeed = (Input.GetKey(KeyCode.LeftShift)) ? fastSpeed : normalSpeed; | |
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow)) | |
{ | |
_newPosition += (transform.forward * _movementSpeed); | |
} | |
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow)) | |
{ | |
_newPosition -= (transform.forward * _movementSpeed); | |
} | |
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow)) | |
{ | |
_newPosition += (transform.right * _movementSpeed); | |
} | |
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow)) | |
{ | |
_newPosition -= (transform.right * _movementSpeed); | |
} | |
if (Input.GetKey(KeyCode.Q)) | |
{ | |
_newRotation *= Quaternion.Euler(Vector3.up * rotationAmount); | |
} | |
if (Input.GetKey(KeyCode.E)) | |
{ | |
_newRotation *= Quaternion.Euler(Vector3.down * rotationAmount); | |
} | |
if (Input.GetKey(KeyCode.R)) | |
{ | |
_newZoom += zoomAmount; | |
} | |
if (Input.GetKey(KeyCode.F)) | |
{ | |
_newZoom -= zoomAmount; | |
} | |
transform.position = Vector3.Lerp(transform.position, _newPosition, Time.deltaTime * movementTime); | |
transform.rotation = Quaternion.Lerp(transform.rotation, _newRotation, Time.deltaTime * movementTime); | |
cam.transform.localPosition = Vector3.Lerp(cam.transform.localPosition, _newZoom, Time.deltaTime * movementTime); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
From my YT comment: At 5:25 (line 143) Beware this kind of lerp is not good as described in https://gamedevbeginner.com/the-right-way-to-lerp-in-unity-with-examples/ section "Lerp slowing down at the end (and how to stop it)" indeed t should vary from 0 to 1 (0 .. 100%). But let suppose t = 10% to make it simple (using a small and fixed dt and small speed and large distance). The first iteration you lerp from the original position to the destination position and your new next position will be 10% of the distance. In the second iteration, you still jump 10% of the new distance. After X iterations you have almost reached the destination, but you still have a small gap and you are keeping using 10% of the distance. After an infinite time, you still lerping of 10% between the destination and the destination minus epsilon (0.000 ... 01). Of course, this is a hack allowing to write shorter code but adding a comment should be fine to prevent people.