コライダーがたくさん接触している時に、特定の数値が一番高いオブジェクトだけを取得したいとか、そういうことをするTipsです。
前準備
![collider 複数判定1](https://sunagitsune.com/wp-content/uploads/2022/01/a32fd1f25857b90a00bdc4de9801abe1.gif)
いくつかのオブジェクトにリジッドボディとコライダーを設置し、コレをアタッチしてドラッグで動かせるようにしておきます。
![collider 複数判定2](https://sunagitsune.com/wp-content/uploads/2022/01/58896a1c0ddb2f2752d089dc1c056919.gif)
適当なオブジェクトを別に用意し、
![collider 複数判定3](https://sunagitsune.com/wp-content/uploads/2022/01/6517c84ff6ff3d6094e80298a57bca41.gif)
OnTriggerStay2Dメソッドで箱に接触しているオブジェクトを検知できるようにしておきます。
//Unity C#
void OnTriggerStay2D(Collider2D other)
{
other.GetComponent<SpriteRenderer>().color += new Color(0, 0, 0, -0.05f);
}
たとえばこんな感じのコードを書くと、
![collider 複数判定4](https://sunagitsune.com/wp-content/uploads/2022/01/b7facb189433c274c4abd087a694a0bf.gif)
箱の中に入ったオブジェクトが透明になります。
今回やりたいのは、複数のオブジェクトが箱に接触している時に、条件を満たすものだけにこういった干渉をする(あるいはデータを取得する)という操作です。
FlagがTrueの時だけ処理を実行
![collider 複数判定5](https://sunagitsune.com/wp-content/uploads/2022/01/d91fafbcbca9121ccd2204deb3ca90b9.gif)
条件が「変数やスクリプトがあるかないか」であれば割と話は簡単です。
ネコのほうにはON/OFFするためのbool値を設定し、箱には以下のような条件を追加します。
ドラッグするオブジェクトなのに名前がcatClickなのは気にしないでください(変え忘れました)。
ネコのほうには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](https://sunagitsune.com/wp-content/uploads/2022/01/e3d47c4ed7d0fd65eb06a52b6d726f5d.gif)
オブジェクトによって任意にboxFlagをONにしたりOFFにしたりしておけば、
![collider 複数判定8](https://sunagitsune.com/wp-content/uploads/2022/01/e24c986ac512fd963446c9524fc12c50.gif)
複数のコライダーが接触していても、条件を満たすものだけに処理が実行される状態が達成できます。
数値が最も大きいオブジェクトに処理を実行
![collider 複数判定9](https://sunagitsune.com/wp-content/uploads/2022/01/12a13188e4f1e728de6d6054a6756bd6.jpg)
今度は変数が最も大きいオブジェクトにだけ処理を実行してみたいと思います。
![collider 複数判定10](https://sunagitsune.com/wp-content/uploads/2022/01/0da9b607f88195b42be73d6437753198.jpg)
オブジェクトごとにそれぞれ1~4の異なる数値を振っておきます。
オブジェクトをリスト化
![collider 複数判定11](https://sunagitsune.com/wp-content/uploads/2022/01/3dc909c3c16c5ac4e71d5a61c4b4a359-1.jpg)
オブジェクトの変数をリスト化するために動的配列を作ります。List<int> boxNumbers = new List<int>();と記述してboxNumbersという名前のintのリストを作り、
![collider 複数判定12](https://sunagitsune.com/wp-content/uploads/2022/01/0444efbd0e39f76f13c804e0a4c10485.jpg)
リストにちゃんと追加されてるか確認するために、テキストを取得しておきます。
![collider 複数判定13](https://sunagitsune.com/wp-content/uploads/2022/01/89e0e0922195d93e7e934872b69bd034-1.jpg)
箱の中に入ってきたオブジェクトの変数boxNumberをOnTriggerEnter2D時にAddでリストに追加し、Countで取得したリストの長さをテキストに表示してみると、
![collider 複数判定14](https://sunagitsune.com/wp-content/uploads/2022/01/07c524527449ea0c3add2efc42f043db.gif)
ちゃんと追加されていること、オブジェクトの数=リストの長さになることが確認できます。
![collider 複数判定15](https://sunagitsune.com/wp-content/uploads/2022/01/a332ffc90891bb217d7ee693bcb5ba09-1.jpg)
逆に箱から出た時はOnTriggerExit2DでRemoveし、リストから変数を削除すればOK。
ついでに箱から外に出すと色を元に戻すようにしておきます。
ついでに箱から外に出すと色を元に戻すようにしておきます。
変数の最大値を求める
![collider 複数判定16](https://sunagitsune.com/wp-content/uploads/2022/01/7436b04dd249b0f72d940bd51fb802e7.jpg)
リストboxNumbersの最大値を求めるには、Mathf.Max(boxNumbers.ToArray());のように記述します。
入った時と出た時に最大値を取得し、その都度textに代入すると、
入った時と出た時に最大値を取得し、その都度textに代入すると、
![collider 複数判定17](https://sunagitsune.com/wp-content/uploads/2022/01/929d8c6c83a29f4192a46ecae3501abd.gif)
今箱の中にある変数の中で、最大のものが常に表示されるようになります。
![collider 複数判定17](https://sunagitsune.com/wp-content/uploads/2022/01/929d8c6c83a29f4192a46ecae3501abd.jpg)
または、リストをSortして昇順に並べ替えた後、boxNumbers[boxNumbers.Count – 1]のように求めても最大値が求められます(ただし初期状態でインデックスがマイナスになるので、例外処理しないとエラー表示が出ます)。
変数が一番大きいオブジェクトに処理を実行
![collider 複数判定18](https://sunagitsune.com/wp-content/uploads/2022/01/24e9b870b64c5f3e70e76d8cf1053990.jpg)
基本的には操作したオブジェクトの変数が最大値と一致してたら色を変える、という感じになりますが、
![collider 複数判定19](https://sunagitsune.com/wp-content/uploads/2022/01/21a21b88297390ef1e1a94bffec8e9d9.gif)
これだけだともっと大きな値のオブジェクトが入ってきた時色がそのまま残るので、
![collider 複数判定20](https://sunagitsune.com/wp-content/uploads/2022/01/0af4eab9c32d1a3e0b59cf79b9312735.jpg)
たとえばオブジェクトもリスト化してしまって、
![collider 複数判定22](https://sunagitsune.com/wp-content/uploads/2022/01/4e10aee4b60c311881dab2f311832b6c-650x213.jpg)
繰り返し処理で、オブジェクトが増減するたびに最大値以外のオブジェクトは元の色に戻すようにすれば、
![collider 複数判定23](https://sunagitsune.com/wp-content/uploads/2022/01/824c153d1724abe40f6a0ce0ee86d7f6.gif)
ちょっと無理矢理ですが、意図は達成できます。
//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++;
}
}
}
![](https://sunagitsune.com/wp-content/uploads/2021/07/computer-1343393_1280-160x90.jpg)
やりたいことから逆引きするUNITYの使い方まとめ
Unityをやりたいことから学習していけるよう、機能・用途別にまとめたページです。C#の命令別の逆引きは現時点で作っていません。2019の時期に書き始めているので、それより前のバージョンについては言及しません。
コメント