もどくんちゃんねる ガジェット部

自転車、ガジェット、映像制作、CG、Blender など

UNITYでVRを接続したときに、cam.ScreenPointToRay()の方向がおかしくなってしまう対処法【Oculus】

 

こんにちは。今日紹介するのは、UnityでVRを接続したときに、レイキャストヒットがおかしくなってしまう対処法を紹介します。

 

目次

 

 

発生した問題

具体的にいうとこれですね。

Ray ray = cam.ScreenPointToRay(new Vector3(corner.x, corner.y, 10));

 

本当は、スクリーン上の点をがカメラの視錐台でどこに届くかを計算するはずですが、VRを接続していないと、正常なのに、VRを接続した途端おかしくなるやつです。

 

研究のシステムで発生した問題なので、画像は見せられなくてごめんなさい。

 

原因

どうやら、ScreenPointToRayの視錐台の情報の一部がVRを接続すると、設定したカメラではなく、VRのカメラに強制的に変わってしまうことが原因のようです。

 

困っちゃいますね。こちらでも嘆いている人がたくさんいました。

forum.unity.com

 

 

解決策

解決策としては、screenPointToRayを自作しちゃえばいいんです。

ということで自作したプログラムは以下の通りです。

 

public Ray CustomScreenPointToRay(Vector3 screenPoint)
    {
        // スクリーン空間の点をワールド空間に変換(自作の関数を使用)
        Vector3 pointInWorldSpace = CustomScreenToWorldPoint(new Vector3(screenPoint.x, screenPoint.y, cam.nearClipPlane));

        // レイの方向を計算
        Vector3 rayDirection = pointInWorldSpace - cam.transform.position;

        // レイを生成
        return new Ray(cam.transform.position, rayDirection);
    }

    public Vector3 CustomScreenToWorldPoint(Vector3 screenPoint)
    {
        // スクリーン座標の正規化
        Vector3 normalizedPoint = new Vector3(screenPoint.x / Screen.width, screenPoint.y / Screen.height, screenPoint.z);

        // ビューポート座標への変換(透視投影の逆変換は省略)
        Vector3 viewportPoint = cam.ViewportToWorldPoint(normalizedPoint);

        // ワールド空間への変換(カメラの位置と向きを考慮)
        // (透視投影の完全な逆変換を行うには、カメラの透視投影行列の逆行列計算が必要)

        return viewportPoint;
    }

 

camには自分で使いたいカメラを設定してください。

そして最後に、メインカメラ(VRでは無いカメラ)の設定の中の「ターゲットアイ」を「なし(メインディスプレイ)」に変更してください。

 

何故かはわからないですが、これでレイキャストがうまくいきます。

これですべて解決するはずです。

 

めでたしめでたし。

本当は自作じゃなくて、ChatGPTに作らせたんですけどね笑。こういう問題は色々調べるよりChatGPTに作らせちゃうのが一番です笑