LoginSignup
0
0

More than 3 years have passed since last update.

【Unity】ある水平軸に対して指定オブジェクトが上側にあるか、下側にあるかの判定方法

Last updated at Posted at 2021-03-22

はじめに

タイトルの通り、ある水平軸に対して指定オブジェクト(今回はカメラ)が上側にあるか、下側にあるかを判定する方法についてまとめます。
上下判定01.png

Script及び注意点

まず、スクリプトから

    public bool  IsUp(Transform Target,Transform Cam)
    {
        var diff = Target.transform.position - Cam.transform.position;
        var axis = Vector3.Cross(Target.transform.forward,diff);
        return axis.x > 0;
    } 

判定自体はこの三行で行えます。

しかし、注意点として例えばTargetの原点が以下のように足元(0地点)にある場合、Target.transform.fowrdで求まる水平軸は足元にくるため、カメラが真下に潜り込まない限り基本的には判定は常にTrueが返ってきてしまいます。
上下判定02.png
よって、Targetの中央高さを基準水平軸としたい場合は、Targetの子として空のオブジェクトを配置し、そのオブジェクトをTargetにセットすることで解決します。
上下判定03.png

なぜ、この判定を行う必要があったのか

そもそもなぜこのような判定方法を取る必要があったかというと、Unityにおいて回転の値はEditor上で入力する「-50」と「310」は全く同じ角度となります。

しかしながら、この値をスクリプトから取得すると、返ってくるのはどちらの値でも「310」が返ってきます。
こうなると何が困るかというと、例えばCam01からCam02に回転値「-50」を引き継ぐ場合、以下のような事が起こりえます。
上下判定04.png
そのため、何らかの方法で回転値を判定し、正しい値を受け渡す処理が必要だったわけです。

今回はベクトルから上下を判定しましたが、調べた中でもう一つ簡単に判定する方法も見つけたので、併せて紹介しておきます。

おまけ(回転値を+180~-180に整える)

    public float AdjustAngle180(float angle)
    {
        float subNormal = Mathf.Floor((angle + 180f) / 360f) * 360f;
        return (angle > 0f) ? angle - subNormal : angle;
    }

angleに回転値を渡します、渡す際はtransform.rotation.eulerAnglesでQuaternion型からVecotr3型にキャストしてから渡しましょう。
subNormalは「0」または「360」となります、水平軸より上側なら「0」、下側なら「360」です。

これを0以上かどうか判定し、0以上の場合は取得したangleから-360してマイナスの値に、そうでなければそのままの値を返します。
上下判定05.png

結果としては先述したベクトルから求める方法と同じ結果となるため、どちらを使っても問題ないと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0