我如何设置合适的截锥体大小,以便移动相机需要始终将对象(例如 3D 模型)完全保持在场景中,而不能靠得太近以至于该对象的一部分被切断.
模型不动。
如果相机始终指向您的对象并且对象位于屏幕中心,您可以在此处轻松解决此问题https://docs.unity3d.com/Manual/FrustumSizeAtDistance.html 。但一般来说,这个类可以完成任务. 首先,您需要考虑一个围绕您的对象的虚拟球体,它完全包含您的对象,并且此代码可避免对象离开屏幕。
public class PutObjectAlwaysInScreen : MonoBehaviour {
//Object Transform that should be in the screen
public Transform Target;
//Considering a sphere around your object according to its size
public float Radius;
void check()
{
//Finding a frustum plate that include object position point
//the vector from camera to frustum plate
Vector3 Vcenter = Camera.main.transform.forward;
//Vector between camera and object
Vector3 VcameraToObject = Target.position - Camera.main.transform.position;
//The angle between center of frustum and object postion
float CosTeta = Vector3.Dot(Vcenter,VcameraToObject)/(Vcenter.magnitude * VcameraToObject.magnitude);
//distance between camera and frustum
float distance = VcameraToObject.magnitude * CosTeta;
//Center of frustum plate
Vector3 Fcenter = Camera.main.transform.position + distance * (Vcenter/Vcenter.magnitude);
//Vector between center of frustum and object
Vector3 FrustumToObject = Target.position - Fcenter;
//Width And Height of the distance between center of frustum and object in the screen
float W = Vector3.Dot(FrustumToObject,Camera.main.transform.right);
float H = Vector3.Dot(FrustumToObject,Camera.main.transform.up);
//frustum Width and Height
float frustumHeight = 2.0f * distance * Mathf.Tan(Camera.main.fieldOfView * 0.5f * Mathf.Deg2Rad);
float frustumWidth = frustumHeight * Camera.main.aspect;
//Check if the object is out of the screen
if( ((Mathf.Abs(W)+Radius)>frustumWidth) || ((Mathf.Abs(H)+Radius)>frustumHeight) )
{
// Do Something
// You Can Avoid Camera from getting closer to the Object
//or With the below formulae adjust the fieldOfView
if((Mathf.Abs(W)+Radius)>frustumHeight)
Camera.main.fieldOfView = 2.0f * Mathf.Atan((Mathf.Abs(H)+Radius) * 0.5f / distance) * Mathf.Rad2Deg;
if((Mathf.Abs(W)+Radius)>frustumWidth)
Camera.main.fieldOfView = 2.0f * Mathf.Atan(((Mathf.Abs(W)+Radius)/Camera.main.aspect) * 0.5f / distance) * Mathf.Rad2Deg;
}
}
void Update() {
check();
}
}