Unity相机范围适应物体大小
情形
相机是游戏向玩家展示的主要手段。大部分时候,相机的位置和范围可以提前设定,在游戏中不会做变化。但有些时候,我们希望相机在游戏当中能够调整位置和范围,以显示某一物体。
具体一点,说一下我遇到的情况。我希望显示的物体是一个由玩家自定义自己制造的飞船。这个飞船可大可小,在玩家把它做出来之前,游戏是无法确定它的大小的。自然地,用来跟随飞船的摄像机也无法确定位置和范围。我希望在玩家制作完毕飞船之后,能够使相机适应飞船的尺寸,在屏幕中合适的显示出飞船的全部。
方法
下面提供我的解决方法。我的解决方法假设相机正对需要适应显示的物体的中心。如果不是这样,需要对代码做一些小改动,但总体做法是适用的。
public class CameraManager:MonoBehaviour
{
// 对摄像机的引用,可以在面板中设置,也可以在初始化时获取。
public Camera cam;
// 需要显示的物体的中心位置。
public Transform root;
// 物体的半径。即物体里中心最远的地方到中心的距离。
public float radius;
// 一些参数,在面板中调试。
// 两个参数增大都会使屏幕中物体变小。
// 半径和相机范围的关系参数
public float radiusToSizeFactor=2;
// 半径和相机距离的关系参数
public float radiusToDistanceFactor=2;
// 传入物体的中心位置和物体半径。
public void PrepareCamera(Transform center, float r)
{
// 根据参数设置相机到物体的距离。
cam.transform.localPosition = new Vector3(0, 0, -radiusToDistanceFactor * radius);
// 如果需要显示的物体不是正对相机中心,修改这个向量的初值。
Vector3 worldPos = new Vector3(0, radius, 0);
// 把向量转换到世界坐标系,因为相机的接口只接受世界坐标
worldPos = root.TransformPoint(worldPos);
// 获得点在相机屏幕中的相对位置,如正好在屏幕左下角的点返回(0, 0, z),正好在右上角的点返回(1, 1, z)。z为物体离相机的深度距离,在这里没有用处。
Vector3 viewPos = cam.WorldToViewportPoint(worldPos);
// 根据参数调整相机范围。这里我用的是正交相机,如果使用透视相机,这里应该修改fieldOfView。
// 如果参数为2,则物体最多占到屏幕的1/2高度。
cam.orthographicSize *= radiusToSizeFactor * viewPos.y;
}
}
结语
Unity并没有给出他所用的Camera.orthograpicSize
和Camera.fieldOfView
是如何计算的,具有什么意义。所以没办法直接计算出合适的值,只能通过相对关系做放大和缩小。还是有那么一点不直观。