VRアプリの開発でパネルが画面に見えないときユーザーに提示を表示する機能を実装してるので、その辺の話検索してみた。その覚え書きです。
Camera.WorldToViewportPoint
で計算する方法
Camera.WorldToViewportPoint
で点の位置がカメラのビューポートに納めてるかどうかを計算する方法。
public bool IsVisibleByCamera() {
Vector3 viewPos = Camera.main.WorldToViewportPoint(transform.position);
// viewPosのx座標とy座標が0以上1以下かつzが0以上だったらみえる
if (viewPos.x >= 0 && viewPos.x <=1 &&
viewPos.y >= 0 && viewPos.y <=1 && viewPos.z >=0) {
Debug.Log("Visible by camera");
return true;
}
else {
Debug.Log("Invisible by camera");
return false;
}
}
この方法では、オブジェクトの中心しか計算していないので、例えばパネルの境界が見えても見えないと判断されてしまう問題があるので、今度の場合は不適切だと思う。
GeometryUtility.TestPlanesAABB
とGeometryUtility.CalculateFrustumPlanes
Unity Community Wikiによるものなんですが、以下のようにカメラの拡張メソッドを書くと
CameraExtensions.cs
public static class CameraExtensions {
public static bool IsVisibleObject(this UnityEngine.Camera @this, Renderer renderer) {
return GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(@this), renderer.bounds);
}
}
このようにメソッドを呼び出したら判断できるはず。
public bool IsVisibleByCamera() {
return Camera.main.IsVisibleObject(GetComponent<Renderer>());
}
ところが、今度はuGUIのimageがカメラの視野に入っているかを検証したいですが、どうやらCanvasRenderer
はRenderer
を継承していないため、MissingComponentExceptionが発生してしまう。今回はオブジェクトにSpriteRenderer
をつけることで解決したが、あんまりいい方法とは思えない。もし記事を読んでいただいた方が何かアドバイスあればコメントをいただけると嬉しいです。
まとめ
-
Camera.WorldToViewportPoint
は点がカメラのビューポートに入ってるかどうかを判断できる。 -
GeometryUtility.TestPlanesAABB
でオブジェクトにつけているレンダラーの境界がすべてカメラのビューポートに入ってるかどうかを判断する -
CanvasRenderer
はSpriteRenderer
やMeshRenderer
などと異なって、Renderer
に継承していない。