If you want to keep the Y and Z rotation constant (and zero I guess), so the ‘horizion’ appears always as a straight line, and it’s always facing say north, you’re going to have to move the camera around with the player, at least in the X and Z planes, while keeping it’s Y coordinates (height) constant, to create a constant 60 degrees diagonal view.
So given the player’s position (this example makes the camera look from south to north (from Vector3.back to Vector3.forward), in a 60 degree angle:
void SetCameraPosition(Transform camera, Transform player, float distanceFromPlayer) {
Quaternion rotate60Upwards = Quaternion.AngleAxis(60, Vector3.right);
Vector3 fromPlayerToCamera = (rotate60Upwards * Vector3.back) * distanceFromPlayer;
camera.position = player.position + fromPlayerToCamera;
camera.rotation = Quaternion.AngleAxis(60, Vector3.right);
}
Now, you can either move the camera the exact same amount that you move the player, whenever the player moves (without rotating the camera any further), or you can simply run the code above every frame (in Update()) so the camera is always updated according to the player location.
Edit: I now understand that you want the camera to stay fixed and rotate, but limit the rotation. What you can do is calculate the most extreme rays of the camera (the corners of the screen), and check that none of them are outside your boundaries. You can do that by placing a huge box collider behind your scene in the area, but only in the area that you want to be visible, so that when there is a point that you don’t want to be visible, the collider will not be behind it. Set a specific layer for this collider, say “AreaLayer”. Then cast the extreme rays with the AreaLayer as a mask, and see if they hit the collider. If they do not, don’t allow the camera to rotate any further:
void FollowPlayer(Transform player) {
Quaternion previousRotation = transform.rotation; // remember original rotation
transform.LookAt(player, Vector3.up); // look at player
// if looking at player caused the camera to turn outside its bounds, restore previous rotation
if (IsCameraOutOfBounds()) {
transform.rotation = previousRotation;
}
}
bool IsCameraOutOfBounds() {
Ray[] edgeRays = GetCameraEdgeRays(); // get camera extreme rays
int layerMask = 1 << LayerMask.NameToLayer("AreaLayer"); // raycast layer should only find the "AreaLayer" collider - the collider that depicts the game area
foreach (Ray ray in edgeRays) {
// if raycast doesn't hit the area layer collider, camera is out of bounds
if (!Physics.Raycast(ray, Mathf.Infinity, layerMask) {
return true;
}
}
return false;
}
// get 4 rays, one for each corner of the camera's view
Ray[] GetCameraEdgeRays() {
Ray[] rays = Ray[4];
ray[0] = camera.ScreenPointToRay(0, 0);
ray[1] = camera.ScreenPointToRay(0, Screen.height);
ray[2] = camera.ScreenPointToRay(Screen.Width, 0);
ray[3] = camera.ScreenPointToRay(Screen.Width, Screen.height);
return rays;
}
I appreciate the input but I'm really hoping to use a camera that doesn't change its transform to follow the player instead uses LookAt to follow. I'm having a problem with keeping the camera from seeing the end of the map. In the video, the camera stays in one position and uses LookAt to follow the player. As the player reaches an edge of the map, the camera reaches a boundary and stops following the player. That's what I'm trying to do.
– KarnEdgeIt is a much simpler solution I appreciated it.
– Womrwood