Answers for "map boundaries for perspective camera"
http://answers.unity.com/questions/1011399/fix-boundries-for-perspective-camera.html
The latest answers for the question "map boundaries for perspective camera"Answer by Erik-Sombroek
http://answers.unity.com/answers/1012688/view.html
Hi,
In the end i managed to solve it using a virtual Plane infront of the camera that i raycast onto to get the position of where the camera should be to not have the map out of bounds.
Attached image illustrates the concept:
![alt text][1]
[1]: /storage/temp/50716-camera-boundaries.jpg
- A: We first translate the map bound A to the screen space
- B: We thenpush point A to the border of the camera (at the Z depth of point A)
- C: Now we know how much we have to push this vector on the X-axis at given distance so that the Camera is in bounds again.
- D: Here we translate the center of the camera to the world coordinates at distance Z (distance of the A vector).
- E: We then offset point D with the distance we found at C
- F: Now we raycast from point E with a negative direction of camera.forward on to a plane that is placed at the position of the camera with normal facing to camera.forward
Now we know exactly where to place the camera to make sure the camera doesn't go out of the map bounds.
Here is the code, i tried to comment as much as possible:
Vector3 topRightEdgeScreen = Camera.main.WorldToScreenPoint(topRightEdge);
Vector3 downLeftEdgeScreen = Camera.main.WorldToScreenPoint(downLeftEdge);
Debug.Log(downLeftEdgeScreen+" "+Screen.height);
// Is the camera out of the map bounds?
if(topRightEdgeScreen.x < Screen.width || topRightEdgeScreen.y < Screen.height || downLeftEdgeScreen.x > 0 || downLeftEdgeScreen.y>0){
//smack a big plane at the camera position that covers more than the screen is showing
cameraPositionFixPlane = new Plane(Vector3.forward*10, Camera.main.transform.position);
//move the top right edge back so its inside the screen again
Vector3 topRightEdgeScreenFixed = Camera.main.ScreenToWorldPoint(new Vector3(Mathf.Max(Screen.width, topRightEdgeScreen.x), Mathf.Max(Screen.height,topRightEdgeScreen.y), topRightEdgeScreen.z));
//now we know the offset the camera should move at distance z to fix the top right edge
Vector3 topRightOffsetAtDistance = topRightEdgeScreenFixed-topRightEdge;
//this time for the down left edge
Vector3 downLeftEdgeScreenFixed = Camera.main.ScreenToWorldPoint(new Vector3(Mathf.Min(0, downLeftEdgeScreen.x), Mathf.Min(0, downLeftEdgeScreen.y), downLeftEdgeScreen.z));
//now we know the offset the camera should move at distance z to fix the down left edge
Vector3 downLeftOffsetAtDistance = downLeftEdgeScreenFixed-downLeftEdge;
Debug.Log ("offset: "+downLeftOffsetAtDistance);
//where is the center of the screen translated at given distance
Vector3 cameraCenterAtDistance = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width/2.0f, Screen.height/2.0f, topRightEdge.z));
//now lets offset the center of the screen with the offset we found
Vector3 cameraCenterAtDistanceFixed = new Vector3(cameraCenterAtDistance.x-topRightOffsetAtDistance.x-downLeftOffsetAtDistance.x, cameraCenterAtDistance.y-topRightOffsetAtDistance.y-downLeftOffsetAtDistance.y, cameraCenterAtDistance.z);
//here we generate a ray at the camera center at distance pointing back to the camera
Ray rayFromFixedDistanceToCameraPlane = new Ray(cameraCenterAtDistanceFixed, -Camera.main.transform.forward);
//this is where the magic happens, lets raycast back to the plane i smacked infront of the camera
float d;
cameraPositionFixPlane.Raycast(rayFromFixedDistanceToCameraPlane, out d);
//where did the raycast hit the camera plane?
Vector3 planeHitPoint = rayFromFixedDistanceToCameraPlane.GetPoint(d);
//position camera at the hitpoint we found
Camera.main.transform.position = new Vector3(planeHitPoint.x, planeHitPoint.y, Camera.main.transform.position.z);
}
Hope this will help someone!
Best,
Erik SombroekWed, 22 Jul 2015 16:15:58 GMTErik-Sombroek