i-school - ゲーム内のゲームオブジェクトを取得して、最も近いオブジェクトの情報を取得する

ゲーム内の特定の種類のゲームオブジェクトをすべて取得して、その中の最も近いゲームオブジェクトの情報を取得する


 上記の処理を実行するためのSearchGameObjectスクリプトを作成します。
 作成したSearchGameObjectスクリプトを任意のゲームオブジェクトにアタッチすることによって、
アタッチされたゲームオブジェクトから見て最も近い距離にいる別のゲームオブジェクトの情報を取得する、という内容になっています。

 今回のケースではSearchGameObjectスクリプトをプレイヤー役のゲームオブジェクトにアタッチします。
タグには「Enemy」を指定しておいて、ゲーム内に存在するすべての「Enemy」タグを持つゲームオブジェクトをUpdateで常に取得します。
取得したゲームオブジェクトとプレイヤーとの距離をそれぞれ算出し、その差分が最も小さいゲームオブジェクトの情報を取得するようにしています。
 この結果を用いることで、「最も近くにいる敵を対象にとる」というロジックに利用できます。


検証動画(Consoleに取得したゲームオブジェクトの名前が表示されます)
https://gyazo.com/0be28b486ef177e6243898c2d97910b3


SearchGameObjectスクリプトを作成する


SearchGameObject.cs

 <= クリックすると開きます。




 無事に取得できましたら、あとは取得したゲームオブジェクトの情報を他のクラスと紐づけするか、あるいは別のクラスの変数に直接代入するようにすれば利用できるようになります。

インスペクター画像



検証動画(SearchGameObjectのsearchNearObjの値が変化していることを確認します)
https://gyazo.com/6abaff18db8d19357caa742de6a594f8


<リファクタリング>


 Seach メソッド内の処理は LINQ の機能を利用することにより、処理の簡略記述出来ます。


private GameObject Search()
{
    GameObject[] objs = GameObject.FindGameObjectsWithTag(tagName);

    GameObject searchTargetObj = objs
        .OrderBy(obj => Vector3.Distance(obj.transform.position, transform.position))
        .FirstOrDefault();

    return searchTargetObj;
}


 このリファクタリングでは、LINQのOrderByメソッドを使用して、オブジェクトを距離の昇順でソートし、
FirstOrDefaultメソッドで最初のオブジェクトを取得しています。

 これにより、コードが簡潔になり、最も近いオブジェクトを検索する処理がより明示的になりました。


 
 処理が正しく読み解けるようになってきたら、さらなる簡略化が可能です。


private GameObject Search()
{
    return GameObject.FindGameObjectsWithTag(tagName)
        .OrderBy(obj => Vector3.Distance(obj.transform.position, transform.position))
        .FirstOrDefault();
}

 いずれも戻り値の値を利用した、メソッドチェーンによる記法です。