Monday, August 1, 2016

unity - My camera does not rotate around player in 3d open world


I want my camera to following behind the player at all times. When the player turns to the left, I would expect the camera would move behind the player while remaining focused on the player.


My camera stays focused on the player. However, it does not rotate to stay behind the player.


I tried following the directions from here, and here. Neither of which seems to help.


Here's my code:



public class CameraFollow : MonoBehaviour
{

private GameObject player;
private GameObject mainCamera;
private Vector3 offset;
private float distance;
private Vector3 playerPrevPos;
private Vector3 playerMoveDir;


// Use this for initialization
private void Start()
{
player = GameObject.FindGameObjectWithTag("Player");
mainCamera = GameObject.FindGameObjectWithTag("MainCamera");

//Calculate and store the offset value by getting the distance between the player's position and camera's position.
offset = transform.position - player.transform.position;

distance = offset.magnitude;

playerPrevPos = player.transform.position;
}

// Update is called once per frame
private void Update() { }

private void LateUpdate()
{
playerMoveDir = player.transform.position - playerPrevPos;


if (playerMoveDir != Vector3.zero)
{
playerMoveDir.Normalize();
transform.position = player.transform.position + offset;
transform.LookAt(player.transform.position);
transform.rotation = Quaternion.Lerp(transform.rotation, player.transform.rotation, Time.deltaTime * 1);

mainCamera.transform.position = player.transform.position + offset;
mainCamera.transform.LookAt(player.transform.position);
mainCamera.transform.rotation = Quaternion.Lerp(transform.rotation, player.transform.rotation, Time.deltaTime * 1);


playerPrevPos = player.transform.position;
}
}
}

I have done something a little different, per instructions from a online unity class. My main camera is a subobject of a rootobject, as shown in this picture.


enter image description here


I have attached image of the game with the yellow line showing which way the player is facing. The camera is facing in a different direction.


enter image description here



Any help would be appreciated.
Thnx Matt


Follow-up from answers: I cannot get either solution to work. @alejandrodlsp solution doesn't compile (I've added a comment to the answer explaining why). If I do not set offset on Start (aka its always 0), then the camera rotates. The problem is that is at the feet the player and not behind like I wanted. Once I compute offset, then the camera never rotates behind the player.



Answer



I have a solution to what I needed. I appreciate everyone's input. The solution was definitely "outside the box". The key to the solution is this property [gameobject].transform.forward. My other change was to use LateUpdate() as it is called once per frame, rather than FixedUpdate(), since that's called during the physics phase.


[gameobject].transform.forward gives the direction the player is looking at. Obviously, when the player rotates, the vector rotates too. For more info, see this post.


Here's the code.


public class CameraRotateFollow : MonoBehaviour
{
private GameObject player;

private Vector3 distanceVecToPlayer;
private float distanceToPlayer = 3f;
private float cameraHeight = 2f;
private long count = 0;

// Use this for initialization
private void Start()
{
player = GameObject.FindGameObjectWithTag("Player");


// Calculate and store the camera arm position relative to player
// by getting the distance between the player's position and camera arm 's position.
distanceVecToPlayer = transform.position - player.transform.position;

// on start, we are assuming player is facing north (rotation 0, 0, 0) (this is design flaw I can live with)
// therefore transform.position.z is the distance from camera arm to player
// y Height above player
// x is left or right of player (and should always be 0)
distanceToPlayer = distanceVecToPlayer.z;
cameraHeight = distanceVecToPlayer.y;

}

private void LateUpdate()
{
Follow();
}

private void Follow()
{
var forward = player.transform.forward;

float distanceModifer = distanceToPlayer * -1.0f;

// compute camera arm location.
Vector3 setCameraLocation = player.transform.position - distanceModifer * player.transform.forward;

// camera is set above the player (to look over his shoulder). To keep a consistent height
// set height (Vector3.y) to player position (which is techincally at the ground) + starting camera height
setCameraLocation.y = player.transform.position.y + cameraHeight;

// Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.

// this keeps the camera on the same axis as the previous update
transform.position = setCameraLocation;

// make sure camera arm (and hence the camara) is looking at the player
transform.LookAt(player.transform);
}

Thnx again. Everyone's help is appreciated. I wouldn't have been able to think through the problem enough without it.


Matt


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...