- Home /
Camera rotates around player but player movement is incorrect
I am building a third person game where the player is a metal ball and they have to successfully navigate through the maze.
So far, the scripts for the camera enable the Main Camera to follow the player object and when the player turns left or right, the Main Camera will rotate with it, enabling the player to see what is in front of them.
However, when the player turns around or rotates 180 degrees to face the opposite direction to what they started in, the controls for the player object do not match this rotation e.g. once rotated 180 degrees, to go forwards the player has to press backwards.
I have tried many codes from other questions and have googled the hell out of this but I still cant figure it out.
Can anyone help me with this?
Here is my Camera Controller script:
public class CameraController : MonoBehaviour {
public GameObject player;
public float turnSpeed = 1.0f;
private Vector3 offset;
void Start ()
{
offset = transform.position - player.transform.position;
}
void LateUpdate (){
offset = Quaternion.AngleAxis (Input.GetAxis ("Horizontal") * turnSpeed, Vector3.up) * offset;
transform.position = player.transform.position + offset;
transform.LookAt (player.transform.position);
}
}
Can you share your player controller script as well? It sounds like your problem is how the player's moving, not the camera, based on what you've told us.
Thanks for the comment, here is my player controller script:
void FixedUpdate (){
if (isRunning) {
elapsedTime += Time.deltaTime;
}
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
rb.AddForce (movement * speed);
}
Shot in the dark, but "once 180 degrees ___" can sometimes mean you're experiencing gimbal lock.
Pasting your character controller may help clarify what's going on.
Hi guys,
Thanks for the comment, here is my player controller script:
void FixedUpdate (){
if (isRunning) {
elapsedTime += Time.deltaTime;
}
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
rb.AddForce (movement * speed);
}
Answer by MarshallN · Mar 20, 2017 at 10:58 PM
Okay, so what you're doing now is having the rotation of the camera be completely unrelated to the movement of the ball - your script for player movement is based off world coordinates, so its forward axis will always be the same regardless of what direction the camera is facing. Instead, what you want to do is something like
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
private float speed;
private bool isRunning;
private Rigidbody rb;
public GameObject mainCamera;
// Use this for initialization
void Start () {
speed = 1f;
isRunning = true;
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
//void Update()
//{
//}
void FixedUpdate()
{
Vector3 fromCameraToMe = transform.position - mainCamera.transform.position;
fromCameraToMe.y = 0; // First, zero out any vertical component, so the movement plane is always horizontal.
fromCameraToMe.Normalize(); // Then, normalize the vector to length 1 so that we don't affect the player more strongly when the camera is at different distances.
//if (isRunning)
//{
// elapsedTime += Time.deltaTime;
//}
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
//Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
// We can cheat a bit here - we had to flatten out the 'forward' vector from the camera to the player, but the camera is always horizontal left-right, so we can just use
// its 'transform.right' vector to determine the direction to move the ball. Add the horizontal and vertical vectors to determine ground-plane movement.
Vector3 movement = (fromCameraToMe * moveVertical + mainCamera.transform.right * moveHorizontal) * speed;
rb.AddForce(movement * speed);
}
}
Though I'd also recommend having the horizontal input keys change only the camera OR the ball, not both - it leads to a kind of weird circular motion with it changing both simultaneously.
This code is brilliant! exactly what I was looking for, thank you so much. I see what you mean by the circular motion when the input keys are both changing the ball and the camera. What input keys would you recommend to use?
Glad I could help - I think most people expect Q and E for clockwise/counterclockwise rotation, for WASD movement where the mouse isn't used for camera control. If you are using the mouse, obviously that can be used ins$$anonymous$$d of keyboard input.
Your answer
Follow this Question
Related Questions
Mouse Orbit Script with mecanim & turning character 0 Answers
How to make an empty child object not rotate with parent? 1 Answer
How to "clamp" a y rotation in unity? 0 Answers
How to make the main camera rotate with the player's directions? 1 Answer
Using GetAxis("...") for making 180 degree controls 2 Answers