Unity C#で接触する複数のコライダーの中から条件に合うものだけ処理を実行する方法

IT

コライダーがたくさん接触している時に、特定の数値が一番高いオブジェクトだけを取得したいとか、そういうことをするTipsです。

スポンサーリンク

前準備

collider 複数判定1
いくつかのオブジェクトにリジッドボディとコライダーを設置し、コレをアタッチしてドラッグで動かせるようにしておきます。
collider 複数判定2
適当なオブジェクトを別に用意し、
collider 複数判定3
OnTriggerStay2Dメソッドで箱に接触しているオブジェクトを検知できるようにしておきます。
//Unity C#
void OnTriggerStay2D(Collider2D other)
{
other.GetComponent<SpriteRenderer>().color += new Color(0, 0, 0, -0.05f);
}
たとえばこんな感じのコードを書くと、
collider 複数判定4
箱の中に入ったオブジェクトが透明になります。

今回やりたいのは、複数のオブジェクトが箱に接触している時に、条件を満たすものだけにこういった干渉をする(あるいはデータを取得する)という操作です。

FlagがTrueの時だけ処理を実行

collider 複数判定5
条件が「変数やスクリプトがあるかないか」であれば割と話は簡単です。
ネコのほうにはON/OFFするためのbool値を設定し、箱には以下のような条件を追加します。
ドラッグするオブジェクトなのに名前がcatClickなのは気にしないでください(変え忘れました)。
//Unity C#
public class intoBox : MonoBehaviour
{
  //一回スクリプト「catClick」を代入するための変数
    catClick script;

    void OnTriggerStay2D(Collider2D other)
    {
     //接触しているオブジェクトのスクリプト「catClick」をscriptに代入
        script = other.gameObject.GetComponent<catClick>();
     //「catClick」の変数「boxFlag」がTrueの場合処理を実行
        if (script.boxFlag)
        {
            other.GetComponent<SpriteRenderer>().color += new Color(0, 0, 0, -0.05f);
        }

    }
collider 複数判定7
オブジェクトによって任意にboxFlagをONにしたりOFFにしたりしておけば、
collider 複数判定8
複数のコライダーが接触していても、条件を満たすものだけに処理が実行される状態が達成できます。

数値が最も大きいオブジェクトに処理を実行

collider 複数判定9
今度は変数が最も大きいオブジェクトにだけ処理を実行してみたいと思います。
collider 複数判定10
オブジェクトごとにそれぞれ1~4の異なる数値を振っておきます。

オブジェクトをリスト化

collider 複数判定11
オブジェクトの変数をリスト化するために動的配列を作ります。List<int> boxNumbers = new List<int>();と記述してboxNumbersという名前のintのリストを作り、
collider 複数判定12
リストにちゃんと追加されてるか確認するために、テキストを取得しておきます。
collider 複数判定13
箱の中に入ってきたオブジェクトの変数boxNumberをOnTriggerEnter2D時にAddでリストに追加し、Countで取得したリストの長さをテキストに表示してみると、
collider 複数判定14
ちゃんと追加されていること、オブジェクトの数=リストの長さになることが確認できます。
collider 複数判定15
逆に箱から出た時はOnTriggerExit2DRemoveし、リストから変数を削除すればOK。
ついでに箱から外に出すと色を元に戻すようにしておきます。

変数の最大値を求める

collider 複数判定16
リストboxNumbersの最大値を求めるには、Mathf.Max(boxNumbers.ToArray());のように記述します。
入った時と出た時に最大値を取得し、その都度textに代入すると、
collider 複数判定17
今箱の中にある変数の中で、最大のものが常に表示されるようになります。
collider 複数判定17
または、リストをSortして昇順に並べ替えた後、boxNumbers[boxNumbers.Count – 1]のように求めても最大値が求められます(ただし初期状態でインデックスがマイナスになるので、例外処理しないとエラー表示が出ます)。

変数が一番大きいオブジェクトに処理を実行

collider 複数判定18
基本的には操作したオブジェクトの変数が最大値と一致してたら色を変える、という感じになりますが、
collider 複数判定19
これだけだともっと大きな値のオブジェクトが入ってきた時色がそのまま残るので、
collider 複数判定20
たとえばオブジェクトもリスト化してしまって、
collider 複数判定22
繰り返し処理で、オブジェクトが増減するたびに最大値以外のオブジェクトは元の色に戻すようにすれば、
collider 複数判定23
ちょっと無理矢理ですが、意図は達成できます。
//Unity C#
using UnityEngine.UI;

public class intoBox : MonoBehaviour
{
    catClick script;
    catClick script2;
    //長さ表示用
    Text text;
    //変数のリスト
    List boxNumbers = new List();
    //オブジェクトのリスト
    List catObjects = new List();
    //最大値代入用
    int max;

    void Start()
    {
        text = GameObject.Find("Text").GetComponent();
    }

    void OnTriggerEnter2D(Collider2D cat)
    {
        script = cat.gameObject.GetComponent();
        boxNumbers.Add(script.boxNumber);
        catObjects.Add(cat.gameObject);
        max = Mathf.Max(boxNumbers.ToArray());
        text.text = max.ToString();
        int i = 0;
        while(i <= boxNumbers.Count)
        {
            script2 = catObjects[i].GetComponent();
            if (script2.boxNumber == max)
            {
                catObjects[i].gameObject.GetComponent().color = new Color(1f, 0, 1f, 1f);
            }
            else
            {
                catObjects[i].gameObject.GetComponent().color = new Color(1f, 1f, 1f, 1f);
            }
            i++;
        }

    }

    void OnTriggerExit2D(Collider2D cat)
    {
        script = cat.gameObject.GetComponent();
        boxNumbers.Remove(script.boxNumber);
        catObjects.Remove(cat.gameObject);
        cat.GetComponent().color = new Color(1f, 1f, 1f, 1f);
        max = Mathf.Max(boxNumbers.ToArray());
        text.text = max.ToString();
        int i = 0;
        while (i <= boxNumbers.Count)
        {
            script2 = catObjects[i].GetComponent();
            if (script2.boxNumber == max)
            {
                catObjects[i].gameObject.GetComponent().color = new Color(1f, 0, 1f, 1f);
            }
            else
            {
                catObjects[i].gameObject.GetComponent().color = new Color(1f, 1f, 1f, 1f);
            }
            i++;
        }
    }

}
やりたいことから逆引きするUNITYの使い方まとめ
Unityをやりたいことから学習していけるよう、機能・用途別にまとめたページです。C#の命令別の逆引きは現時点で作っていません。2019の時期に書き始めているので、それより前のバージョンについては言及しません。

コメント