Moving forward in world space with rotation.

Hi, I have been trying to make a RTS like camera and so far I have been stuck with a problem. I have managed to get the camera to rotate, zoom in and out and pan left and right but when I try to pan forward I get a problem because it works fine if I dont get rotate the camera but if I do it does not take the rotation into account. I know it is something to do with world space and local space and have researched these topics but I am still stuck because if I move forward in local space it does include rotation but does not scrol along the Z axis instead goes forward into the ground because I have the camera on a angle but if I use world space it does not include rotation. My script so far is down below.Finally I have tried using transform.TransformDirection but wasn’t sure how to properly used it. I also have a diagram to help illustrate the problem :

using UnityEngine;
using System.Collections;

public class cameraControls : MonoBehaviour {

	public float scrollSpeed, cameraSpeed;
	public float pixelEdge = 10f;
	private float mouseX,mouseY;
	private bool isZooming, isRotating, isTranslation;
	private bool controlsOn;

	public Vector3 movement = new Vector3(0,0,0);

	// Use this for initialization
	void Start () {
		controlsOn = false;
	}
	
	// Update is called once per frame
	void Update () {
		if(Input.GetKeyDown(KeyCode.C)){
			controlsOn = !controlsOn;
		}
	
	}

	void HandleMouseRotation(){
		float easeFactor = 10f;
		if(Input.GetMouseButton(1) && Input.GetKey(KeyCode.LeftControl)){
			if(Input.mousePosition.x != mouseX){
				float cameraRotationY = (Input.mousePosition.x - mouseX) * easeFactor * Time.deltaTime;
				this.transform.Rotate(0,cameraRotationY,0,Space.World);
			}
		}

	}

	void Zoom(){
		//Zoom
		if(Input.GetAxis("Mouse ScrollWheel") > 0){
			//transform.Translate(Vector3.forward * Time.deltaTime * scrollSpeed);
			Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView,Camera.main.fieldOfView - scrollSpeed,Time.deltaTime);
		}
		if(Input.GetAxis("Mouse ScrollWheel") < 0){
			//transform.Translate(Vector3.forward * Time.deltaTime * scrollSpeed);
			Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView,Camera.main.fieldOfView + scrollSpeed,Time.deltaTime);
		}
	}

	void cameraTranslation(){
		//Translate	
		if(Input.mousePosition.x > Screen.width - pixelEdge){
			transform.Translate(Vector3.right * Time.deltaTime * cameraSpeed,Space.Self);
		}
		
		if(Input.mousePosition.x < 0 + pixelEdge){
			transform.Translate(Vector3.left * Time.deltaTime * cameraSpeed,Space.Self);
		}
		
		if(Input.mousePosition.y > Screen.height - pixelEdge){
			transform.Translate(Vector3.forward * Time.deltaTime * cameraSpeed,Space.World);


		}
		
		if(Input.mousePosition.y < 0 + pixelEdge){
			transform.Translate(-Vector3.forward * Time.deltaTime * cameraSpeed,Space.World);			
		}

	}

	void LateUpdate(){
		if(controlsOn == true){
			HandleMouseRotation();
			Zoom();
			cameraTranslation();
		}
		mouseX = Input.mousePosition.x;
		mouseY = Input.mousePosition.y;

	}
}

Try this:

Vector direction = transform.forward;
direction.y = 0;
direction.Normalize();
transform.Translate(direction * Time.deltaTime * cameraSpeed, Space.World);

Note that this will not work properly if the camera is aiming (perfectly) straight down or up as that would result in a zero vector.

You could also do it with Quaternion.LookRotation using the scene up (Y-axis) as forward direction and the camera forward as it’s up-axis. This way it’s never at an angle and only rotating around the Y-axis.

Quaternion quat = Quaternion.LookRotation(Vector3.up, transform.forward);

Though that quaternion rotation makes the Z-axis point scene up and then tries to aim the Y-axis to the camera’s forward (so without an angle). Not that useful you would think, though this means that if we apply this rotation to a Vector3.up it will result in the camera’s forward without the angle.

So in theory (at least in my head) using the quaternion from before we can do:

Vector3 direction = Vector3.up * quat;
transform.Translate(direction * Time.deltaTime * cameraSpeed, Space.World);

Out of the top of my head so sorry for any errors. Hope this helps. :slight_smile: