如何计算相机“正确”的位置和距离框架所有我的场景?

考虑我的场景有N个dynamic点,我想用我的相机“框架”所有这些点。 在这里输入图像描述

我如何计算(在运行时)的Vector3位置正确地架设我的所有场景?

这是我的想法:

  1. 为我所有的点计算Avarage

  2. 移动我的相机“向上”正确“框架”我所有的要点(我不知道如何)

  3. 使用Unity LookAt(myAvaragePoint)

谢谢

所以实际上有无限多的点将有资格。 即使我们假设有一个满足你的问题的单个距离值(因为任何距离都大于这个距离也是有效的!但是我们假设你想要这个距离最小的距离),这仍然会使我们可能的每一个可能的旋转围绕相机运行,并保持所有的观点。

这就是说,这是我采取的方法:

  1. find所有点的平均中心。 一个更好的解决方法是计算几何中心1 (因此,距离远处的40个点的距离远不止一个点),但是对于这个样本来说,原始的平均值更容易, “(你的第二步)。

  2. 移动摄像机到这一点,然后向上移动1个单位,然后向后移动( -1 * transform.forward )1个单位,然后看平均中心点。

    • 这会使相机偏离平均值,所以当我们开始将相机从组中移开时,我们不必重新调整视角:我们已经知道这是中心,我们只需将相机向后移动,直到所有的点都可见
  3. find数据集中每个点的屏幕像素坐标。 如果有任何价值观是消极的,他们是在我们的视野之外! 此外,如果X或Y值大于屏幕的大小,它们也在该方向上位于视图之外。

  4. 循环:向后移动相机1个单元,重新检查屏幕上的值。 重复,直到所有点都在屏幕上。

这给了我们这个:

 using UnityEngine; public class FocusInOnAll : MonoBehaviour { public Transform[] allPts; // Use this for initialization void Start () { Vector3 averageCenter = Vector3.zero; bool wasAnyPointOutside = true; foreach(Transform t in allPts) { averageCenter += t.position; Vector3 v = Camera.main.WorldToScreenPoint(t.position); Debug.Log("Point at: " + v); if(vx < 0 || vy < 0 || vz < 0 || vx > Screen.width || vy > Screen.height) { wasAnyPointOutside = true; } } Debug.Log("Center: " + averageCenter / allPts.Length); Camera.main.transform.position = (averageCenter / allPts.Length) + Vector3.up - Camera.main.transform.forward; Camera.main.transform.LookAt((averageCenter / allPts.Length)); while(wasAnyPointOutside) { wasAnyPointOutside = false; Camera.main.transform.position = Camera.main.transform.position - Camera.main.transform.forward; foreach(Transform t in allPts) { Vector3 v = Camera.main.WorldToScreenPoint(t.position); if(vx < 0 || vy < 0 || vz < 0 || vx > Screen.width || vy > Screen.height) { wasAnyPointOutside = true; } } } } } 

1这将通过logging最小和最大的 X和Y值,然后一起平均最小值和最大值来完成。

如果你不太担心performance,那么你可能会进行一个迭代过程。 按照您提到的步骤:

  1. 计算平均排名
  2. LookAt(平均排名)
  3. 沿着它的-transform.forward轴移动相机一个固定的步骤,直到满足条件。

条件是所有点都在视图内:一种方法是迭代每个点,并检查两个轴上的屏幕空间位置是否在0和1之间。 ( https://docs.unity3d.com/ScriptReference/Camera.WorldToViewportPoint.html