Problem updating camera and player movement

Hi everyone,

I’m making a physics-based game (based off of the “Roll-A-Ball” series) where the player is moved using the horizontal and vertical axis’. I want to make it so that when the camera following the player comes into contact with certain triggers, the camera rotates 90* in order to tell the player where they need to go next.

EDIT: I should word this a lot more clearly. In short, how do I make it so that the movement of the player is relative to the direction the camera is facing, so that left is left, right is right, up is up, etc.,.?

If anybody can help me, that’d be great! :smile:

EDIT: Ok, I got the camera positioning fixed and working completely fine now, here’s the updated code:

[FONT=Menlo]using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour
{
    // Get instance of player object
    public GameObject player;

    private Vector3 position;
    private Vector3 oldPosition;
    private Transform myTransform;
    private PlayerController script = new PlayerController();

    void Start()
    {
        myTransform = GetComponent<Transform>();
        script = player.GetComponent<PlayerController>();
        position = new Vector3(0f, 9.5f, -9.5f);
        oldPosition = position;
    }
    

    void Update()
    {
        Quaternion rotation;
        // Determine which way the camera is facing
        if(!script.cameraDir)
        {
            rotation =  Quaternion.Euler(35,0,0);
            myTransform.rotation = Quaternion.Slerp(myTransform.rotation, rotation, Time.deltaTime * 2.5f);
            position = new Vector3(0f, 9.5f, -9.5f);
            position = Vector3.Lerp(oldPosition, position, Time.deltaTime * 2.5f);
            oldPosition = position;
        }else
        {
            rotation =  Quaternion.Euler(35,90,0);
            myTransform.rotation = Quaternion.Slerp(myTransform.rotation, rotation, Time.deltaTime * 2.5f);
            position = new Vector3(-9.5f, 9.5f, 0f);
            position = Vector3.Lerp(oldPosition, position, Time.deltaTime * 2.5f);
            oldPosition = position;
        }

        // Position the camera above the player
        myTransform.position = player.transform.position + position;
    }
}[/FONT]

And my updated player controller script:

[FONT=Menlo]using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PlayerController : MonoBehaviour
{
    // Declare public variables
    public GUIText gemText;
    public GUIText winText;
    public GUIText livesText;
    public AudioSource gemCollectSound;
    public int amountOfGems;
    public int lives;
    public float speed;
    public float maxSpeed;
    public float jumpHeight;
    public bool cameraDir;

    // Declare private variables
    private int gems;
    private float distanceToGround;
    private bool down;
    private Vector3 movement;

    // Initialize all the things!
    void Start()
    {
        cameraDir = false; // Default camera direction
        distanceToGround = collider.bounds.extents.y;
        gems = 0;
        winText.text = "";
        livesText.text = "Lives: " + lives.ToString();
        SetText();
    }

    // Handle input in fixed update
    void FixedUpdate()
    {
        // Get and store input values
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical   = Input.GetAxis("Vertical");

        // Make sure player isn't rolling too fast
        if(IsGrounded ())
        {
            movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
            rigidbody.velocity = Vector3.ClampMagnitude(rigidbody.velocity, maxSpeed * Time.fixedDeltaTime);
        }else
        {
            movement = new Vector3(moveHorizontal/20, 0, moveVertical/20);
        }

        // Move player
        rigidbody.AddForce(movement * speed * Time.deltaTime);
                
        // Check for jump
        if (Input.GetKey(KeyCode.Space)  IsGrounded())
        {
            rigidbody.AddForce(Vector3.up * jumpHeight, ForceMode.VelocityChange);
        }

        // Check for death
        if (transform.position.y < -10f)
        {
            lives -=1;
            transform.position = new Vector3(0f,0.6f,0f);
            SetText ();
            moveHorizontal = 0f;
            moveVertical = 0f;
        }
    }

    // Determine if player is on ground or not
    bool IsGrounded()
    {
        return Physics.Raycast(transform.position, -Vector3.up, distanceToGround + 0.1f);
    }

    // Pickup gems
    void OnTriggerEnter(Collider other)
    {
        // Pickup gems
        if(other.gameObject.tag == "PickUp")
        {
            gemCollectSound.Play();
            other.gameObject.SetActive(false);
            gems += 1;
            SetText();
        }

        // Change camera
        if(other.gameObject.tag == "CameraWaypoint")
        {
            cameraDir = !cameraDir;
        }
    }

    void SetText()
    {
        // Print game info to screen
        gemText.text = "Gems Collected: " + gems.ToString() +" / " + amountOfGems;
        livesText.text = "Lives: " + lives.ToString();

        if (gems >= amountOfGems)
        {
            winText.text = "YOU WIN!";
        }
    }
}
[/FONT]

In this line of code you’re calculating a desired movement in world space:

movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

To calculate it instead relative to the camera, you need to work out in which directions you want the horizontal and vertical inputs to move the player.

For horizontal you probably want to use the camera’s right vector, and for vertical you probably want its forward vector, but you might also want to ensure that those are flat - especially the forward vector.

So, copy those vectors, zero the Y components, normalize them, and use those to form the new movement vector:

Vector3 flatRight = camera.transform.right;
flatRight.y = 0;
flatRight.Normalize();

Vector3 flatForward = camera.transform.forward;
flatForward.y = 0;
flatForward.Normalize();

movement = moveHorizontal * flatRight + moveVertical * flatForward;

Thank you so much gfoot, that did the job perfectly! :smile:

Glad to see it’s a pretty simple process, the posts on Answers and old threads I managed to find made it so over-complicated (not to mention didn’t work, hence my posting here!), although I do admit I’m having a hard time following exactly how it works (I’m super new to Unity). I guess I just need to study up a bit more!

Again, thanks so much!

Great! This is not really Unity, it is general vector maths, so any tutorials you can find should be useful, they don’t have to be Unity-specific.

The main thing you’ll pick up is an awareness of how to formulate the direction you’re thinking of in your head in terms of the orientations of objects in your scene, then you can use those vectors to construct the direction you want in the code.

Also note that new Vector3(amountX, amountY, amountZ) means the same things as amountX * Vector3.right + amountY * Vector3.up + amountZ * Vector3.forward, and when you remember that, then it is obvious that you can substitute completely different vectors if you want to.