Tuesday, February 5, 2019

unity - How to place a camera so that it always fits a plane?


I have a plane that can get its scale changed during the game, and I want to make the camera view it completely every time the plane has its scale changed. The only camera is set to perspective projection.


I found this page which tells me how to resize the plane (I do not understand the unity of measure used there) to be viewed by the camera, and I want the reverse.


I found something similar here.


I also found other not-very-relevant answers by googling "unity camera fits a plane", "unity move camera to show an object" (one of the results is this), "unity field of view to fit an object" (one of the results is this).


I think I found the answer here, but it is hard for me to do the maths right now. I also found an answer here but I wish that someone explained me the mathematics (also, I do not know how to get the bounds).



My relevant previous question with the same situation is here. There is a link to download a sample project, and a few screenshots.


Thank you.



Answer



I have found the answer here. Although it is not completely explained mathematically in my opinion, it works well.


The code I use is like this:


private void Start()
{
// ...

PositionCamera();

}

///
/// Source: https://forum.unity.com/threads/dynamic-loaded-object-fit-to-screen-size.349794/
///

void PositionCamera()
{
GameObject ObjectToView = GameObject.Find("Background");
Camera camera = Camera.main;


Bounds objectBounds = ObjectToView.GetComponent().bounds;
Vector3 objectFrontCenter = objectBounds.center - ObjectToView.transform.forward * objectBounds.extents.z;

//Get the far side of the triangle by going up from the center, at a 90 degree angle of the camera's forward vector.
Vector3 triangleFarSideUpAxis = Quaternion.AngleAxis(90, ObjectToView.transform.right) * transform.forward;
//Calculate the up point of the triangle.
const float MARGIN_MULTIPLIER = 1f;
Vector3 triangleUpPoint = objectFrontCenter + triangleFarSideUpAxis * objectBounds.extents.y * MARGIN_MULTIPLIER;

//The angle between the camera and the top point of the triangle is half the field of view.

//The tangent of this angle equals the length of the opposing triangle side over the desired distance between the camera and the object's front.
float desiredDistance = Vector3.Distance(triangleUpPoint, objectFrontCenter) / Mathf.Tan(Mathf.Deg2Rad * camera.GetComponent().fieldOfView / 2);

camera.transform.position = -camera.transform.forward * desiredDistance + objectFrontCenter;
}

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...