コライダーがたくさん接触している時に、特定の数値が一番高いオブジェクトだけを取得したいとか、そういうことをするTipsです。
前準備
いくつかのオブジェクトにリジッドボディとコライダーを設置し、コレをアタッチしてドラッグで動かせるようにしておきます。
適当なオブジェクトを別に用意し、
OnTriggerStay2Dメソッドで箱に接触しているオブジェクトを検知できるようにしておきます。
//Unity C#
void OnTriggerStay2D(Collider2D other)
{
other.GetComponent<SpriteRenderer>().color += new Color(0, 0, 0, -0.05f);
}
たとえばこんな感じのコードを書くと、
箱の中に入ったオブジェクトが透明になります。
今回やりたいのは、複数のオブジェクトが箱に接触している時に、条件を満たすものだけにこういった干渉をする(あるいはデータを取得する)という操作です。
FlagがTrueの時だけ処理を実行
条件が「変数やスクリプトがあるかないか」であれば割と話は簡単です。
ネコのほうには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);
}
}
オブジェクトによって任意にboxFlagをONにしたりOFFにしたりしておけば、
複数のコライダーが接触していても、条件を満たすものだけに処理が実行される状態が達成できます。
数値が最も大きいオブジェクトに処理を実行
今度は変数が最も大きいオブジェクトにだけ処理を実行してみたいと思います。
オブジェクトごとにそれぞれ1~4の異なる数値を振っておきます。
オブジェクトをリスト化
オブジェクトの変数をリスト化するために動的配列を作ります。List<int> boxNumbers = new List<int>();と記述してboxNumbersという名前のintのリストを作り、
リストにちゃんと追加されてるか確認するために、テキストを取得しておきます。
箱の中に入ってきたオブジェクトの変数boxNumberをOnTriggerEnter2D時にAddでリストに追加し、Countで取得したリストの長さをテキストに表示してみると、
ちゃんと追加されていること、オブジェクトの数=リストの長さになることが確認できます。
逆に箱から出た時はOnTriggerExit2DでRemoveし、リストから変数を削除すればOK。
ついでに箱から外に出すと色を元に戻すようにしておきます。
ついでに箱から外に出すと色を元に戻すようにしておきます。
変数の最大値を求める
リストboxNumbersの最大値を求めるには、Mathf.Max(boxNumbers.ToArray());のように記述します。
入った時と出た時に最大値を取得し、その都度textに代入すると、
入った時と出た時に最大値を取得し、その都度textに代入すると、
今箱の中にある変数の中で、最大のものが常に表示されるようになります。
または、リストをSortして昇順に並べ替えた後、boxNumbers[boxNumbers.Count – 1]のように求めても最大値が求められます(ただし初期状態でインデックスがマイナスになるので、例外処理しないとエラー表示が出ます)。
変数が一番大きいオブジェクトに処理を実行
基本的には操作したオブジェクトの変数が最大値と一致してたら色を変える、という感じになりますが、
これだけだともっと大きな値のオブジェクトが入ってきた時色がそのまま残るので、
たとえばオブジェクトもリスト化してしまって、
繰り返し処理で、オブジェクトが増減するたびに最大値以外のオブジェクトは元の色に戻すようにすれば、
ちょっと無理矢理ですが、意図は達成できます。
//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の時期に書き始めているので、それより前のバージョンについては言及しません。
コメント