Skip to content

Instantly share code, notes, and snippets.

@KraigWalker
Created October 19, 2013 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KraigWalker/7057132 to your computer and use it in GitHub Desktop.
Save KraigWalker/7057132 to your computer and use it in GitHub Desktop.
not a final script
public class CameraController : MonoBehaviour {
public bool useCInput = false; // whether or not to use cInput 2.x
public Transform focusTarget; // we look at and follow this
[HideInInspector]
// How fast the camera moves
public int cameraVelocity = 10;
public float distance = 100.0f; // not even sure if this should be customizable...
// position variables
private float posX;
private float posY;
private float posZ;
public bool moveToPositionInstantly = true; // if true then instantly move to position
// rotation variables
private float angle = 30.0f;
public bool rotateBy45 = false;
public bool invertRotation = false; // quick way to make the "rotate left" button rotate to the right, and vice versa.
private float rotationOffset = 315.0f;
private Quaternion targetRotation;
public float rotationDamping = 6.0f; // a higher value will rotate the camera faster
public bool rotateInstantly = false; // if true then instantly rotate to position
// Keep track of the rotation
private int currentAngle = 1; // Initialize to position 1
// zoom variables
private float targetZoom;
public bool invertZoom = false; // quick way to make the "zoom in" button zoom out, and vice versa.
private int zoomSizesIndex = 0;
public float zoomDamping = 6.0f; // a higher value will zoom the camera faster
public float[] zoomSizes = new float[] { 2.5f, 5.0f, 10.0f, 20.0f };
public bool zoomInstantly = false; // if true then instantly set zoom amount
public Transform cameraContainer;
// Use this for initialization
void Start () {
// Create a container object to make camera rotation and movement easier
// camContainer= GameObject.Find("cameraContainer").transform;
cameraContainer = new GameObject("cameraContainer").transform;
// Set the camera's movement parent to our cameraContainer
cameraContainer.position = new Vector3(0, 0, 0);
transform.parent = cameraContainer;
// check to make sure we have something to focus on
if (!focusTarget) {
Debug.LogWarning("WARNING: Nothing specified to look at. Setting focustTarget to camContainer.");
focusTarget = cameraContainer;
}
// Ensure that the camera we're using is an Orthographic camera
if(camera.orthographic == false)
{
camera.orthographic = true;
}
// Set the initial position of the camera.
// You can adjust this by changing the position of MainCamera
// in the editor.
cameraContainer.position = new Vector3(transform.position.x,
transform.position.y,
transform.position.z);
// Set the initial rotation
transform.rotation = Quaternion.Euler(angle, rotationOffset, 0f);
targetRotation = cameraContainer.rotation;
// Select our zoom level from the array of zoom sizes
targetZoom = zoomSizes[zoomSizesIndex];
// Set camera to initial values
setCamPos();
setContainerPos(true);
rotateCam(true);
zoomCam(true);
transform.position = new Vector3(posX, posY, posZ);
}
// Update is called once per frame
void Update () {
checkInputs();
// Raycast from the camera to get what's in the center
// of the viewport
Ray ray = camera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
RaycastHit hit;
if(Physics.Raycast(ray, out hit))
{
//print("I'm looking at " + hit.transform.name);
}
else
{
//print("I'm looking at nothing!");
}
}
void LateUpdate() {
setContainerPos(false);
rotateCam(false);
zoomCam(false);
}
void rotateCam(bool instant) {
// this is where the rotation takes place
if(targetRotation != cameraContainer.rotation) {
if(instant) {
cameraContainer.rotation = targetRotation;
} else {
// Rotate the camera smoothly over time - needs explanation
cameraContainer.rotation = Quaternion.Slerp(
cameraContainer.rotation,
targetRotation,
Time.deltaTime * rotationDamping);
// check for when we're really close to the target rotation
// and if so, finish the whole rotation
if(Mathf.Abs(cameraContainer.rotation.eulerAngles.y - targetRotation.eulerAngles.y) < 0.1) {
targetRotation.eulerAngles = new Vector3(targetRotation.eulerAngles.x, Mathf.RoundToInt(targetRotation.eulerAngles.y), targetRotation.eulerAngles.z);
cameraContainer.eulerAngles = new Vector3(targetRotation.eulerAngles.x, targetRotation.eulerAngles.y, targetRotation.eulerAngles.z);
}
}
}
// else { }
}
//////////////////////////////////////////////////
// Move Along Dual-Axis
//////////////////////////////////////////////////
void moveAlongXZ(bool invertAxis1 = false, bool invertAxis2 = false)
{
int sign1 = 1;
int sign2 = 1;
if(invertAxis1 == true)
sign1 = -1;
if(invertAxis2 == true)
sign2 = 1;
posX += ((this.cameraVelocity*Time.deltaTime) * sign1);
posZ += ((this.cameraVelocity*Time.deltaTime) * sign1);
transform.position = new Vector3(posX, posY, posZ);
}
void moveAlongXY(bool invertAxis1 = false, bool invertAxis2 = false)
{
int sign1 = 1;
int sign2 = 1;
if(invertAxis1 == true)
sign1 = -1;
if(invertAxis2 == true)
sign2 = 1;
posX += ((this.cameraVelocity*Time.deltaTime) * sign1);
posY += ((this.cameraVelocity*Time.deltaTime) * sign2);
transform.position = new Vector3(posX, posY, posZ);
}
void moveAlongYZ(bool invertAxis1 = false, bool invertAxis2 = false)
{
int sign1 = 1;
int sign2 = 1;
if(invertAxis1 == true)
sign1 = -1;
if(invertAxis2 == true)
sign2 = 1;
posY += ((this.cameraVelocity*Time.deltaTime) * sign1);
posZ += ((this.cameraVelocity*Time.deltaTime) * sign2);
transform.position = new Vector3(posX, posY, posZ);
}
//////////////////////////////////////////////////
// Single Axis movement
//////////////////////////////////////////////////
void moveAlongX(bool inverted)
{
int sign = 1;
if(inverted == true)
sign = -1;
posX += ((cameraVelocity*Time.deltaTime) * sign);
transform.position = new Vector3(posX, posY, posZ);
}
void moveAlongY(bool inverted)
{
int sign = 1;
if(inverted == true)
sign = -1;
posY += ((cameraVelocity*Time.deltaTime) * sign);
transform.position = new Vector3(posX, posY, posZ);
}
void moveAlongZ(bool inverted)
{
int sign = 1;
if(inverted == true)
sign = -1;
posZ += ((cameraVelocity*Time.deltaTime) * sign);
transform.position = new Vector3(posX, posY, posZ);
}
//////////////////////////////////////////////////
// Triple Axis movement
//////////////////////////////////////////////////
void moveAlongXYZ(bool invertAxis1 = false, bool invertAxis2 = false, bool invertAxis3 = false)
{
int sign1 = 1;
int sign2 = 1;
int sign3 = 1;
if(invertAxis1 == true)
sign1 = -1;
if(invertAxis2 == true)
sign2 = -1;
if(invertAxis3 == true)
sign3 = -1;
posX += ((this.cameraVelocity*Time.deltaTime) * sign1);
posY += ((this.cameraVelocity*Time.deltaTime) * sign2);
posZ += ((this.cameraVelocity*Time.deltaTime) * sign3);
transform.position = new Vector3(posX, posY, posZ);
}
void checkInputs()
{
// Left
bool invertHorizontal;
if((Input.GetKey(KeyCode.LeftArrow)))
{
Debug.Log("Left Pressed");
switch(currentAngle)
{
case 1:
moveAlongXZ(true, true);
break;
case 2:
moveAlongXY(false, true);
break;
case 3:
moveAlongXZ(false, false);
break;
case 4:
moveAlongXZ(false);
break;
}
}
// Right
if((Input.GetKey(KeyCode.RightArrow)))
{
Debug.Log("Right Pressed");
switch(currentAngle)
{
case 1:
moveAlongXZ(false, false);
break;
case 2:
moveAlongYZ(false, false);
break;
case 3:
moveAlongXZ(true, true);
break;
case 4:
moveAlongXZ(true);
break;
}
}
// Up
if((Input.GetKey(KeyCode.UpArrow)))
{
Debug.Log("Up Pressed");
switch(currentAngle)
{
case 1:
moveAlongY(false);
break;
case 2:
moveAlongY(false);
break;
case 3:
moveAlongY(true);
break;
case 4:
moveAlongXZ(true);
break;
}
}
// Down
if(Input.GetKey(KeyCode.DownArrow))
{
Debug.Log("Down Pressed");
switch(currentAngle)
{
case 1:
moveAlongY(true);
break;
case 2:
moveAlongY(true);
break;
case 3:
moveAlongY(false);
break;
case 4:
moveAlongXZ(true);
break;
}
}
if(Input.GetKeyDown(KeyCode.Keypad1) || Input.GetKeyDown(KeyCode.LeftBracket)) {
rotateLeft();
}
if(Input.GetKeyDown(KeyCode.Keypad3) || Input.GetKeyDown(KeyCode.RightBracket)) {
rotateRight();
}
if (Input.GetKeyDown(KeyCode.Keypad7) || Input.GetKeyDown(KeyCode.S)) {
zoomCamOut();
}
if (Input.GetKeyDown(KeyCode.Keypad9) || Input.GetKeyDown(KeyCode.W)) {
zoomCamIn();
}
}
// Update the desired rotation based on player input
void setRotationTarget(bool rotateRight = true) {
int sign;
int amount = -90;
if(rotateRight) {
sign = 1;
} else {
sign = -1;
}
if(rotateBy45) { amount = -45; }
if(invertRotation) { amount *= -1; }
targetRotation.eulerAngles = new Vector3(targetRotation.eulerAngles.x,
targetRotation.eulerAngles.y + amount * sign,
targetRotation.eulerAngles.z);
}
void rotateLeft() {
if(currentAngle == 1)
{
currentAngle = 4;
} else {
currentAngle -= 1;
}
setRotationTarget(false);
Debug.Log("Current Angle: " + currentAngle);
}
void rotateRight() {
if(currentAngle == 4)
{
currentAngle = 1;
} else {
currentAngle += 1;
}
setRotationTarget(true);
Debug.Log("Current Angle: " + currentAngle);
}
void zoomCam(bool instant) {
float camZoom = camera.orthographicSize;
float diff;
//change zoom over time smoothly
if(!instant) {
if(targetZoom != camZoom) {
diff = targetZoom - camZoom;
camera.orthographicSize += diff * Time.deltaTime * zoomDamping;
if (Mathf.Abs(diff) < 0.01) {
Camera.main.orthographicSize = targetZoom;
}
}
} else { // instantly change the zoom
camera.orthographicSize = targetZoom;
}
}
void setZoomTarget(bool zoomIn) {
if (zoomIn) {
zoomSizesIndex -= 1;
} else {
zoomSizesIndex += 1;
}
// Mathf.Repeat is similar to the modulo operator, but it only works
// with values below 0.
zoomSizesIndex = (int)Mathf.Repeat(zoomSizesIndex, zoomSizes.Length);
targetZoom = zoomSizes[zoomSizesIndex];
}
void zoomCamIn() {
if(invertZoom) {
setZoomTarget(false);
} else {
setZoomTarget(true);
}
}
void zoomCamOut() {
if(invertZoom) {
setZoomTarget(true);
} else {
setZoomTarget(false);
}
}
void setContainerPos(bool instant) {
if(cameraContainer.position != focusTarget.position) {
if(instant) {
cameraContainer.position = focusTarget.position;
} else {
//Debug.Log("We haven't yet set up a smooth cam position so we're not doing it smoothly.");
cameraContainer.position = camera.transform.position;
}
}
}
void setCamPos() {
float dist = FindDist();
float y = FindHeight();
float diag = Mathf.Sqrt((dist * dist) * 2) / 2;
var pos = new Vector3(diag, y, -diag) + cameraContainer.position;
transform.position = pos;
}
// x (on 2D xy plane)
float FindDist() {
var rads = angle * Mathf.Deg2Rad;
var dist = Mathf.Sin(rads) * distance;
return dist;
}
// y (on 2D xy plane)
float FindHeight() {
var rads = angle * Mathf.Deg2Rad;
var height = Mathf.Cos(rads) * distance;
return height;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment