Having trouble with Vectors

Hi there.

I’m having a bit of difficulty with getting the Vector I need and thought I’d turn to the forums for help.

In my game, a camera is attached to an empty gameObject. The gameObject is located in the center of the world, and this object slowly rotates, causing the camera to pivot around the origin. The camera itself is elevated, further away from the center and is angled downward at about -40 degree rotation.
Situated at the origin of the world is a flat piece of terrain which acts as an arena for players to move around on top of, and do battle on.

What I want to do is create a script that will move my player characters around in that arena relative to the camera’s current orientation. When the player moves the joystick “up” or presses ‘W’ on the keyboard, the player’s character should always move away from the camera on this 2d terrain.


In order to accomplish this, as far as I know, I first need to take the XZ vector of Camera.main.foward (relative to the camera’s position) and do some kind of operation alongside the normalized 2d input vector from the players movement.

To put it another way, I need to find an operation that allows me to return a Vector2 with a bearing equal to the sum of 2 other Vector’s bearings. For example, if I have two vector2s A) 0,1 (a 90 degree bearing) and B) -1, 1 ( a 135 degree bearing), I need to find an operation that will give me vector C) -1, -1 (which has a bearing of 90+135). In the above examples the first vector can be thought of as the ‘cameras XZ forward facing vector’ and the second vector can be thought of as the ‘user axis input’.

Does anyone know what operation I therefore need to use? I thought it was Quaternion.FromToRotation that I needed, but I can’t get it to work and am less sure about that now.

Here is the code I have so far:

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour {

	public float Speed = 3.0f;

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update ()
	{
		//Rotate the player to always face away from the camera (on a 2d plane)
		Vector3 NorthOfPlayer = new Vector3 (gameObject.transform.position.x + GetCameraNorth ().x, 1.0f, gameObject.transform.position.z + GetCameraNorth ().y);
		transform.LookAt (NorthOfPlayer);

		//Move the character in relation to the camera's XZ orientation
		if (Input.GetAxis ("Horizontal") != 0 || Input.GetAxis ("Vertical") != 0)
		{
			transform.Translate (new Vector3(GetMoveDirection().x * Time.deltaTime * Speed, 0, GetMoveDirection().z * Time.deltaTime * Speed));
		}
	}

	Vector2 GetCameraNorth ()
	{
		//Find the forward facing vector of the camera (relative to the camera position) if it were on a 2d plane
		Vector2 CameraNorth = new Vector2 (Camera.main.transform.forward.x, Camera.main.transform.forward.z);
		Vector2 Offset = CameraNorth - new Vector2(Camera.main.transform.position.x, Camera.main.transform.position.z);
		return Offset.normalized;
	}

	Vector3 GetMoveDirection ()
	{
		//Get the player input as a 2d vector
		Vector3 MovementInput = new Vector3 (Input.GetAxis ("Horizontal"), 0, Input.GetAxis ("Vertical"));
		Vector3 NormalizedMovementInput = MovementInput.normalized;

		//Combine both the input vector and the camera vector to create the desired direction for the player character to eventually move
		Quaternion q = Quaternion.FromToRotation (Vector3.up, NormalizedMovementInput);
		Vector3 CameraNorthVec3 = new Vector3 (GetCameraNorth().x, 0, GetCameraNorth().y);
		Vector3 v = q * CameraNorthVec3;
		return v;
	}
}

You could project the Camera’s forward and right vectors onto the xz plane, then just use those 3D vectors like so

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float Speed = 3.0f;
    
    void Update()
    {
        float inputVert = Input.GetAxis("Vertical");
        float inputHorz = Input.GetAxis("Horizontal");

        Vector3 normal = Vector3.up;

        Vector3 right = Vector3.ProjectOnPlane(Camera.main.transform.right, normal).normalized; // camera's right vector projected onto xz plane
        Vector3 forward = Vector3.ProjectOnPlane(Camera.main.transform.forward, normal).normalized; // camera's forward vector projected onto xz plane

        if (forward != Vector3.zero) // if vector is zero, Quaternion.LookRotation would throw an error
            transform.rotation = Quaternion.LookRotation(forward); // look along the xz plane according to the camera's forward

        if (inputHorz != 0f) // if moving right/left
        {
            transform.position += right * inputHorz * Speed * Time.deltaTime; // move along camera's right
        }
        if (inputVert != 0f) // if moving forward/backward
        {
            transform.position += forward * inputVert * Speed * Time.deltaTime; // move along camera's forward
        }
    }
}