LoginSignup
10
2

More than 5 years have passed since last update.

LayerMaskに存在するGameObjectを取得する[Unity脱初心者への道]

Last updated at Posted at 2019-04-07

親子で結んだり共通のTagを持っているGameObjectは簡単にScene中から探し出せますが、Layerに属するGameObjectを見つけてくるものが探しても無かったので、作ってみました。

LayerMaskでGameObjectを探す

最初にScriptを出すと、こういう感じです。

    public static GameObject[] FindGameObjectsWithLayerMask(LayerMask layerMask)
    {
        GameObject[] goArray = GameObject.FindObjectsOfType<GameObject>();
        List<GameObject> goList = new List<GameObject>();
        foreach (GameObject go in goArray) {
            // LayerMask bit check
            if (((1 << go.layer) & layerMask.value) != 0) {
                goList.Add(go);
            }
        }
        if (goList.Count == 0) {
            return null;
        }
        return goList.ToArray();
    }

探す方法の解説

1. とりあえず、Findで先ず、全てのGameObjectを拾ってきます
2. その中で、LayerがLayerMaskでビットが立っているかを確認します
3. 立っていたGameObjectをListに突っ込みます
4. 発見が出来なくてListが空ならnull、発見が出来でListの要素があったら配列にして返します。

LayerMaskの解説

GameObject.layerはint型

単純な整数型になっていて、どのLayerか一つ、指定されます。エディタの画面を見ると、こういう感じです。
image.png
例えばこの例では、Playerを指定していると、gameObject.layer=13になります。

参考:UnityリファレンスGameObject.layer
https://docs.unity3d.com/jp/current/ScriptReference/GameObject-layer.html

LayerMaskはビット列

それに対して、LayerMaskは同じくint型なのですが、これの中で複数のLayerを指定できています。これはどういう仕組みなのかというと、
右から数えたビット数のところが1のところが有効なLayer

という仕組みです。例えば、上記のCover=8Ground=10が有効な場合は以下のようになります。

15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0

指定位置のビットが1かをみる方法

この仕組みを理解すると、シフト演算と論理積で確認ができます。

if (((1 << go.layer) & layerMask.value) != 0)

の部分です。

  • 1 << go.layerで左シフトし、LayerMaskの位置に合わせます。
  • その値と論理積をとり、指定位置が1の場合は同じ値、0の場合は演算結果が0になります。

補足

これが簡単と思って実装していますが、今のC#ならBitArrayを用いることも可能です。試してみた人はどうぞ!
やってない理由は、バイナリレベルで考えるとほぼ同じビット操作になるので、CPUリソースで差が無さそうと思ったからです。まあ、やってないので気になる方はどうぞw

10
2
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
10
2