見出し画像

【Unity】ボーリングのピンが倒れたかどうかの判定

現在開発中のスマホ用フォークリフトゲームにてリフトで鉄球を転がしてボーリングのようなステージを作りました。その時にピンが倒れたかどうかを判定する私なりの方法をば。

やりたい事

単純に倒れただけの判定なら、ピンが倒れた時に床と接触する部分にコライダーを仕込めばいいんですが、問題は倒れてはいるけども他のピンと折り重なった状態のときにどう判定させるかです。
ちなみにこちらがピンです↓

このピンがこうなった時にどう判定するか?↓

他のピンにもたれかかっている

実際のボーリングではこれをどう判定するかは知りませんが私のゲームでは45度以上倒れたらOK判定させようと思います。

スクリプト

ピンにアタッチしたスクリプトがこちらです。↓

using System;
using UnityEngine;

public class PinFallJudge : MonoBehaviour
{
    private bool judge=false;
    private Rigidbody rb;
    private bool down=false;//倒れたかどうか

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if(!down)
        {
            if(!judge)//判定の開始
            {
                if(rb.velocity.magnitude > 0)judge=true;
            }

            if(judge)//判定中
            {
                //動作が停止したら判定の終了;
                if(rb.velocity.magnitude==0)Judgement();
            }
        }
    }
    
    void Judgement()//x,zの値の判定
    {
        var x=transform.rotation.eulerAngles.x;
        var z=transform.rotation.eulerAngles.z;
        Func<float, bool> isInRange = rot => rot >= 45f && x <= 315f;

        //x、zどちらかが45度以上回転していればクリア判定
        if(isInRange(x)||isInRange(z))
        {
            down=true;
            //Debug.Log("倒れた");
        }
        else return;

        //Debug.Log("x="+x+"z="+z);
        judge=false;
    }
}

Update内から見ていきます。

if(rb.velocity.magnitude > 0)judge=true;

Rigidbodyに動きがあったらjudgeをtrueにします。これはピンに何かしらの動きがあるまでは何もしないようにさせてます。

if(rb.velocity.magnitude==0)Judgement();
Rigidbodyに何かしらの動きがあった後、動きが止まった時にJudgementメソッドを実行。つまりピンが動いて動きが止まったら判定をします。

続いてJudgement()メソッド内を見ていきます。

var x=transform.rotation.eulerAngles.x;
var z=transform.rotation.eulerAngles.z;

rotationのX、Zの値を取得。

Func<float, bool> isInRange = rot => rot >= 45f && x <= 315f;
ここでfloatを受け取って値が45~315以内であればfalse,そうでなければtrueを返すようにしています。ここで値を変更すればよりシビアにしたりガバガバにしたりできますね。
つまり、ピンのrotationのX,Zが45度より傾いていなければ倒れたと判定しません!ということになります。
(正直このコードの書き方はあまり綺麗ではないのかもしれません)

if(isInRange(x)||isInRange(z)){}
先ほどのisInRange()にX,Zの値を渡して判定を受け取り、どちらかがtrueなら倒れたと判定し、倒れた時の処理を書きます。


この記事が気に入ったらサポートをしてみませんか?