特定の型のインスタンスをすべて取得して操作
FindObjectsByType<T>()メソッドを使って、高速に複数のオブジェクトを操作する方法をみていきましょう
FindObjectsByType<T>()メソッドとは
FindObjectsByType<T>()メソッドは、FindObjectsOfType<T>()メソッドの実装を効率化により高速化したバージョンです
FindObjectsOfType<T>()メソッド
FindObjectsOfType()メソッドは、Unityのゲームオブジェクトの中から、指定されたコンポーネントの型(T)を持つものを全て取得するための静的メソッドです。
引数のTには、取得したいコンポーネントの型を指定します。例えば、FindObjectsOfType()とすると、全てのTransformコンポーネントを持つゲームオブジェクトを取得できます。
このメソッドは、複数のゲームオブジェクトから特定のコンポーネントを取得するために使用されます。例えば、特定のコンポーネントを持つゲームオブジェクトを取得して、それらに対して一括で操作を行うことができます。
ただし、このメソッドはパフォーマンスに影響するため、使用には注意が必要です。ゲームオブジェクトの数が多い場合や、頻繁に呼び出される場合には、適切な最適化が必要です。また、このメソッドは他のコンポーネントを探すためにも使えますが、探す対象になるコンポーネントが多い場合にもパフォーマンスに悪影響を与えることがあるため、使用する場合には注意が必要です。
Helthが特定の値以下になったものはDestroyしたい
各オブジェクト(Cube)に設定されているHealthの値をチェックして、20より小さければ、0を再代入するサンプルを作ってみましょう
なお、Cubeは自分のHealthを常に確認していて0以下になったら削除されるようにしてあります
実行結果
シーンのゲームオブジェクト構成
Cubeを4つとGameManagerのゲームオブジェクトを配置しておきます
Cube1
Cube2
Cube1と同じオブジェクトとしますが、Helthだけ20にしておきます
Cube3
Cube1と同じオブジェクトとしますが、Helthだけ20にしておきます
Cube4
Cube1と同じオブジェクトとしますが、Helthだけ20にしておきます
GameManager
各Cubeを操作するためのスクリプトがアタッチされています
スクリプト
Statusスクリプト
各Cubeにアタッチされています
using UnityEngine;
public class Status : MonoBehaviour
{
public int Health;
void Update()
{
if (Health <= 0)
{
Destroy(gameObject);
}
}
}
このコードは、Unityゲームエンジンで動作するスクリプトで、オブジェクトの状態を管理するためのものです。
using UnityEngine;
は、Unityのクラスを使用するための名前空間の宣言です。
public class Status : MonoBehaviour
は、Status
という名前のクラスを定義し、MonoBehaviour
クラスを継承することを示しています。MonoBehaviour
クラスは、Unityのゲームオブジェクトにアタッチされるスクリプトの基本クラスです。
public int Helth;
は、Helth
という名前の公開された(外部からアクセス可能な)整数型の変数を宣言しています。
void Update()
は、Unityが毎フレーム呼び出す特別なメソッドで、このスクリプトがアタッチされたオブジェクトの状態を更新するために使用されます。
if (Helth <= 0)
は、Helth
変数が0以下になった場合に、以下のブロックを実行する条件文です。
Destroy(gameObject);
は、このスクリプトがアタッチされたオブジェクト自体を削除するためのUnity関数です。gameObject
は、このスクリプトがアタッチされているオブジェクト自体を表す特別な変数です。
つまり、このスクリプトは、Helth
変数が0以下になった場合に、このスクリプトがアタッチされたオブジェクトを破棄するという動作をします。これにより、ゲームオブジェクトの状態を管理することができます。
HealthCheckerスクリプト
using System.Linq;
using UnityEngine;
public class HealthChecker : MonoBehaviour
{
void Start()
{
var enemiesWithStatus = FindObjectsByType<Status>(FindObjectsSortMode.None);
var enemiesOver20helth = enemiesWithStatus.Where(enemy => enemy.Health > 20);
foreach (var enemy in enemiesOver20helth)
{
enemy.Health = 0;
}
}
}
このコードは、UnityのゲームオブジェクトにアタッチされたHealthChecker
というコンポーネントを定義しています。このコンポーネントは、ゲームオブジェクトのStart
関数が実行されると、敵キャラクターのStatus
コンポーネントを持つオブジェクトを見つけ、その中でヘルスが20以上の敵キャラクターのヘルスを0に設定するものです。
具体的には、以下のように機能します。
using System.Linq;
とUnityEngine;
をインポートしています。HealthChecker
クラスは、MonoBehaviour
を継承しています。Start()
関数は、ゲームオブジェクトがアクティブになったときに呼び出されます。FindObjectsByType
関数は、指定されたコンポーネントタイプを持つすべてのオブジェクトを取得します。引数にはFindObjectsSortMode
があり、オブジェクトの並び順を制御します。この例では、None
を指定しているため、オブジェクトの並び順は変更されません。enemiesWithStatus
は、Status
コンポーネントを持つすべてのオブジェクトのリストです。Where
関数は、条件を満たす要素を取り出すために使用されます。この例では、enemy.Health > 20
という条件を指定しています。したがって、enemiesOver20helth
は、ヘルスが20以上の敵キャラクターのリストです。foreach
ループは、enemiesOver20helth
の各要素に対して、enemy.Health = 0
を実行します。つまり、ヘルスが20以上の敵キャラクターのヘルスを0に設定します。
以上のように、このコードはUnityのゲームオブジェクトで、Status
コンポーネントを持つ敵キャラクターのうち、ヘルスが20以上のものを見つけ、ヘルスを0に設定します。
RigidBodyがアタッチされている条件で、重力で落ちるようにする
各オブジェクト(Cube)で、RigidBodyがアタッチされているものを選択して、useGravityプロパティをtrueにして重力で落下するようにします
実行結果
シーンのゲームオブジェクト構成
Helthが特定の値以下になったものはDestroyしたいの時と基本同じです
アタッチされているスクリプトは削除します
Cube1とCube2にはRigidBodyをアタッチしておきます
また、GameManagerには次のようなスクリプトをアタッチしておきます
スクリプト
GravityAddスクリプト
using UnityEngine;
public class GravityAdd : MonoBehaviour
{
void Start()
{
var enemiesWithGravity = FindObjectsByType<Rigidbody>(FindObjectsSortMode.None);
foreach (var eneny in enemiesWithGravity)
{
eneny.useGravity = true;
}
}
}
このコードは、Unityエンジンで動作するC#スクリプトで、GravityAddという名前のクラスが定義されています。
このスクリプトは、オブジェクトの開始時にStart()メソッドが呼び出され、シーン内の全てのRigidbodyコンポーネントを持つ敵オブジェクトを検索し、それぞれのRigidbodyコンポーネントのuseGravityプロパティをtrueに設定します。
具体的には、FindObjectsByType(FindObjectsSortMode.None)メソッドが、Rigidbodyコンポーネントを持つ全てのオブジェクトを検索し、enemiesWithGravityという変数に格納します。次に、foreachループを使って、enemiesWithGravityリスト内の全てのオブジェクトに対して、useGravityプロパティをtrueに設定します。
つまり、このスクリプトは、シーン内の全ての敵オブジェクトに対して、重力を有効にするという処理を行います。
必須ではないですが、次のような記述もできます
using System.Linq;
using UnityEngine;
public class GravityAdd : MonoBehaviour
{
void Start()
{
var enemiesWithGravity = FindObjectsByType<Rigidbody>(FindObjectsSortMode.None);
enemiesWithGravity.ToList().ForEach(enemy => enemy.useGravity = true);
}
}
ForEach() メソッドを使用して、リスト内のすべてのオブジェクトに対して、useGravity プロパティを true に設定して重力を有効にします。ForEach() メソッドは、ラムダ式を引数に取り、リスト内の各要素に対して同じ処理を実行します。このスクリプトでは、ラムダ式内で enemy.useGravity = true を実行することで、各 Rigidbody コンポーネントの useGravity プロパティを true に設定しています。
ディスカッション
コメント一覧
まだ、コメントがありません