1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Unity】リストを扱うときはforeachよりもLINQ使った方がシンプル。.Select(hoge=>fuga)みたいなやつ。【LINQ】

Last updated at Posted at 2020-11-11

Unityで複数のゲームオブジェクトを配列で取得するときがあります。
例えばGameObject.FindGameObjectsWithTagを使ってGameObject型の配列で取ってきたり、Physics.RaycastAllでRaycastHit型の配列で取ってきたり。
配列に何かしらの処理をする時は、forループやforeachループよりも一旦リストに変換してからLINQライブラリを使うと記述がシンプルになります。

【環境】

・MacOS Catalina 10.15.7
・Unity versiton:2019.4.14f1

各要素に戻り値のない処理をしたい→ForEach

例えばFindGameObjectsWithTagで取得したゲームオブジェクトたちの名前をコンソールに書き出したい時。

※Selectとの使い分けはこちらの記事を参考にさせていただきました。
 LINQのそのForEach、実はSelectで書き換えられるかも

LinqTest.cs
using System.Collections.Generic;
using UnityEngine;

public class LinqTest : MonoBehaviour
{
    void Start()
    {
        //PlayerタグをつけたGameObjectを配列で取得しリストへ変換
        List<GameObject> gameObjects = GameObject.FindGameObjectsWithTag("Player").ToList();
        //取得したGameObjectの名前をコンソールに出力
        gameObjects.ForEach(gameObj => print(gameObj.transform.name));
    }
}

各要素に戻り値のある処理をしたい→Select

例えばRaycastHit型で取得したゲームオブジェクトたちをGameObject型のリストに変更したい時。
Case2のまとめて記述する場合は、こちらの記事を参考にさせていただきました。
【Unity】自キャラに一番近いオブジェクトを対象とするロックオン方式の実装

LinqTest.cs
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class LinqTest : MonoBehaviour
{
    void Start()
    {
        //Case1:段階に分けて記述する場合
        List<RaycastHit> hits1 = Physics.SphereCastAll(transform.position,10.0f,transform.forward,0.01f).;
        List<RaycastHit> hits1_RH_list = new List<RaycastHit>(hits1);
        List<GameObject> hits1_GO_list = hits1_RH_list.Select(h => h.transform.gameObject).ToList();

        //Case2:まとめて記述する場合
        var hits2 = Physics.SphereCastAll(transform.position,10.0f,transform.forward,0.01f)
        .Select(h => h.transform.gameObject).ToList();
    }
}

各要素を条件に応じて絞り込みたい→Where

例えばSphereCastAllで取得したゲームオブジェクトの中で、特定の名前("Player1")のオブジェクトだけに絞りたい時。

LinqTest.cs
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class LinqTest : MonoBehaviour
{
    void Start()
    {
        var hits3 = Physics.SphereCastAll(transform.position, 10.0f, transform.forward, 0.01f)
       .Where(h => h.transform.gameObject.name == "Player1").ToList();
    }
}

各要素を条件付きで絞り込んだ後に処理したい→WhereとSelectの組み合わせ

例えばSphereCastAllで取得したゲームオブジェクトの中で、特定の名前("Player1")のオブジェクトだけに絞り、その座標をリストで取得したい時。

LinqTest.cs
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class LinqTest : MonoBehaviour
{
    void Start()
    {
        var hits4 = Physics.SphereCastAll(transform.position, 10.0f, transform.forward, 0.01f)
        .Where(h => h.transform.gameObject.name == "Player1")
            .Select(h => h.transform.position).ToList();
    }
}

こちらの記事も参考にさせていただきました。
【LINQのメソッド紹介その1】foreachメソッドの概要とコード例
【LINQのメソッド紹介その2】Selectの概要とコードの例
【LINQのメソッド紹介その3】Whereで条件に合うデータを取得する

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?