Unityのゲームオブジェクトが現在アクティブかどうかをスクリプトで調べ、アクティブであれば何らかの処理を実行させる。
といった場面はよくあります。
通常であればgameObject.activeSelfを使ってそのゲームオブジェクトがアクティブかどうかを調べる事が出来ます。
ですが、場合によってはactiveSelfを使うと間違った処理になってしまう事があります。
activeSelf
ゲームオブジェクトのactiveSelfを調べればそのゲームオブジェクトがアクティブかどうかを調べる事が出来ます。
しかし、調べるゲームオブジェクトが他のゲームオブジェクトの子要素であって親のゲームオブジェクトが非アクティブだった場合に問題が発生します。
ヒエラルキー上で右クリック→Create Emptyで空のゲームオブジェクトを2つ作り、名前をParent、ChildにしChildをParentの子要素へとドラッグ&ドロップします。
↑のようにParentのインスペクタで名前の横のチェックボックスを外し非アクティブにします。
↑がParentのインスペクタ
↑がChildのインスペクタになり、Parentは非アクティブですがChildはアクティブの状態です。
この状態でそれぞれのゲームオブジェクトがアクティブかどうかを調べるスクリプトを作成しMain Camera等の他のゲームオブジェクトに設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | using UnityEngine; using System.Collections; public class ActiveTest : MonoBehaviour { public GameObject parentObj; public GameObject childObj; // Use this for initialization void Start () { Debug.Log ("ParentAct:" + parentObj.activeSelf); Debug.Log ("ChildAct:" + childObj.activeSelf); } } |
parentObjとchildObjには先ほど作成したゲームオブジェクトをインスペクタで設定します。
Startメソッドでそれぞれのゲームオブジェクトのアクティブを調べ出力しています。
今回はMain CameraにActiveTestスクリプトを設定しインスペクタにParent、Childを設定し実行しました。
↑のようにParentは非アクティブ、Childはアクティブとなります。
このような状態であると親が非アクティブの時は子も非アクティブ扱いにしたい時に困ります。
activeInHierarchy
activeSelfの場合は自身がアクティブかどうかを調べ、親が非アクティブであろうとなかろうと関係がありません。
そこで親が非アクティブであれば子も非アクティブと判定したい場合はactiveInHierarchyを使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using UnityEngine; using System.Collections; public class ActiveTest : MonoBehaviour { public GameObject parentObj; public GameObject childObj; // Use this for initialization void Start () { Debug.Log ("ParentAct:" + parentObj.activeSelf); Debug.Log ("ChildAct:" + childObj.activeSelf); Debug.Log ("ParentActIn:" + parentObj.activeInHierarchy); Debug.Log ("ChildActIn:" + childObj.activeInHierarchy); } } |
↑のようにactiveInHierarchyを使った処理を追加します。
先ほどと同じようにParentは非アクティブ、Childはアクティブ状態にしUnityを実行し確認してみます。
↑のようにactiveInHierarchyを使った場合はChildはアクティブですが親のParentが非アクティブの為にfalseが返ってきています。
ゲームオブジェクトがアクティブかどうかを調べ処理を実行するかどうか分岐させる時に今回のような事ではまってしまうケースもあるかもしれないので、
知っておくと便利ですね(^_^)v