カメラビューポート内のオブジェクトの視線範囲内のポイントを取得する方法

2349 ワード

私たちはHUDをするときによく物体の位置を世界座標点として使います.これは小さな物体の場合は問題ありませんが、大型物体にはちょっと面倒です.私たちの視点では必ずしもこの点が見えるとは限らないので、
例えばビル、大橋、道路などは、物体が視線範囲内に入るときに、現在の視線範囲内の物体が画面の中心に最も近い点を取得し、HUDの世界座標点として表示することを望む.
  1. まず、物体が可視範囲にあるかどうかをテストする必要がある、一般的にOnBecameVisible()ライフサイクルを使用すればよい.
  2. 表示範囲内で画面の中心に最も近い点を取得する、これは多角形面上のある点であってもよく、必ずしも多角形の点ではない.
  3. 画角は三角形であるため、不規則な物体はカメラに最も近い点がカメラの画角内にないことが多い.
  4. あまり複雑にできない
 
そこでライフサイクルから始め、カメラ視点に入るときにリストに追加します.ColliderのAPIに依存し、このColliderが凸多角形であることが必要なので、MeshColliderを判断します.
    private void OnBecameVisible()
    {
        var collider = GetComponent();
        if(collider)
        {
            var mc = collider as MeshCollider;
            if(mc && mc.convex == false)
            {
                return;
            }
            visibleColliders.Add(collider);
        }
    }

そしてカメラが動いているので、位置の計算にもUpdateが必要です
    public static IEnumerator Run()
    {
        while(true)
        {
            if(visibleColliders.Count > 0)
            {
                foreach(var visibleCollider in visibleColliders)
                {
                    var nearestPoint = visibleCollider.ClosestPoint(GetCameraViewPoint(visibleCollider));
                    onVisible.Invoke(visibleCollider, nearestPoint);
                }
            }
            yield return null;
        }
    }

肝心なのはスクリーンの中心から最も近い位置を計算することです.スクリーンの中心は放射線を出すことができるからです.これがスクリーンの中心の線分です.理論によると、頂点が必ずスクリーンの視線の範囲内にあるとは限らない.
これは分かりやすいでしょう.一つの面がカメラの視線を通っていますが、すべての点がカメラの視線の範囲内にないので、簡単な数学的方法で線分に最も近い点を得るのは意味がありません.
ここではColliderが持参したAPIを用いて大まかな値を計算すればよい.
    private static Vector3 GetCameraViewPoint(Collider target)
    {
        var dis = (Camera.main.transform.position - target.bounds.center).magnitude;
        var pos = Camera.main.transform.position + Camera.main.transform.forward * dis;
        return pos;
    }

ここではカメラから物体の中心位置までの距離を参考にして、カメラから放射される放射線をこの距離の点で計算し、その点から物体の最も近い位置まで計算し、得られた位置をHUD世界座標とし、
ほとんどの場合論理的に...
画面がセットできなくて、ジャガイモが届いた.
https://v.youku.com/v_show/id_XNDE4Mzc5MTU5Mg==.html?spm=a2h3j.8428770.3416059.1