今回はSetActive関数についてです。
この関数は簡単に言ってしまえば「オブジェクトのアクティブ状態を切り替える関数」と言えるでしょう。
しかしそもそも「アクティブな状態」とは何なのでしょうか?
まずはその辺りの根幹の部分から入っていきましょう。
続けて実際に「実例」を通し「SetActive関数」を見ていきましょう。
またさらに詳しくなるために以下のような、よくある疑問もまとめてあります。
・アクティブ状態の取得
・切り替え時に呼び出される関数がある
・非アクティブだとfind関数で探せない!
ぜひ最後まで読んでSetActive関数をマスターしましょう!
そもそもアクティブな状態とは?
アクティブ・非アクティブな違い
一言でいえば以下の違いがあります。
アクティブな状態・・・オブジェクトは表示され、Update関数などがちゃんと呼ばれる
非アクティブな状態・・・オブジェクトは表示されず、Update関数なども停止する
つまり非アクティブとは完全に停止している状態と言えるでしょう。
エディタ上でみれば簡単!
ちなみにアクティブ状態は、エディタ上でも簡単に、確認・切り替えが行えます。
アクティブ状態
非アクティブ状態
みなさん一度はこのチェックボックスで、オブジェクトを非表示にしてみたことがあると思います。
これがつまりアクティブ・非アクティブの切り替えボタンだったんですね。
SetActiveとは?
先ほど説明した、アクティブ・非アクティブな状態を切り替える関数です。
使い方は非常にシンプルです。
基本的な使い方
例えば、自分を非アクティブに切り替えたい場合は以下のようにしましょう。
this.gameObject.SetActive (false);
引数にtrue・falseを与えるだけで、アクティブ・非アクティブな状態に変更することができます。
自分のオブジェクトをアクティブにする
this.gameObject.SetActive (true);
自分のオブジェクトを非アクティブにする
this.gameObject.SetActive (false);
その他気をつけること
アクティブ・非アクティブの切り替え時には以下のことに注意しておきましょう。
これらの点を知らずに使用すると思わぬところでつまづくかもしれません。
①親が非アクティブだと、子供も非アクティブな状態になる
②コンポーネントが無効になる。
③スクリプトがUpdate関数など呼ばなくなる
①親が非アクティブだと、子供も非アクティブな状態になる
画像で見てみましょう。
親のオブジェクトを非アクティブ状態にすると?
確かに、子供も表示されなくなりましたね。
ちゃんと非アクティブな状態になるようです。
ただしここで一つ注意点があります。
以下の画像を見てください。
子供である「Cubeオブジェクト」は、親オブジェクトに従い「非アクティブなオブジェクトの挙動」はしますが、自身のアクティブ設定は保持し続けるんです。
アクティブ状態の設定が上書きされたわけでは無いんですね!
つまり次にTestObjectをアクティブな状態にした時には、Cubeも自らの設定に従い、自動的にアクティブ状態に戻ってくれるというわけです。
②コンポーネントが無効になる。
非アクティブな状態になると、所持しているコンポーネントもすべて停止します。
当たり判定や、表示関係の処理も全て停止されるわけです。
③スクリプトがUpdate関数など呼ばなくなる
コンポーネントが無効になるということは、スクリプトも停止されるということです。
つまり回り続けているUpdate関数や、特定のタイミングで発生するメソッドは稼働しなくなります。
これにはちゃんと気をつけてプログラムを組みましょう!
またUpdate関数について詳しく知りたい場合は、以下の記事をご覧ください。
アクティブ状態の判断
現在のアクティブ状態の取得には、以下の二つの関数があります。
・activeSelf
・activeInHierarchy
それぞれの違いを一言でいえば以下となります。
・activeSelf・・・現在のActive設定をbool型で返してくれる関数
・activeInHierarchy・・・ゲーム稼働中に実際にどんな挙動をするかをbool型で返してくれる関数
この違いは、先ほどの【②親が非アクティブだと、子供も非アクティブな状態になる】を思い出してもらえれば簡単ですが…
言葉で説明するのは難しいので、実際に実例で見てみましょう。
実例で見てみよう!
今回は以下のようなサンプルを作成しました。
前回と同じく、「非アクティブな親オブジェクト」「アクティブな子オブジェクト」が存在します。
追加でスクリプト実行用のオブジェクトも存在しますね。
そして実行するスクリプトは以下の通りです。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class ScriptManager : MonoBehaviour { public GameObject testObject; // 非アクティブな親オブジェクト public GameObject cube; // アクティブな子オブジェクト // Use this for initialization void Start () { // 非アクティブな親オブジェクト Debug.Log ("testObject:activeSelf=" + testObject.activeSelf); //activeSelf Debug.Log ("testObject:activeInHierarchy=" + testObject.activeInHierarchy); //activeInHierarchy // アクティブな子オブジェクト Debug.Log ("cube:activeSelf=" + cube.activeSelf); // activeSelf Debug.Log ("cube:activeInHierarchy=" + cube.activeInHierarchy); //activeInHierarchy } }
結果は以下となります。
ここで注目してもらいたいのは、親が非アクティブ状態で、かつ自身がアクティブ状態である「Cubeオブジェクト」の結果です。
「自身のアクティブ状態が取得できるactiveSelf関数」がtrue。
「実際の挙動が取れるactiveInHierarchy」がfalseをそれぞれ返していますね。
つまり今回の例のように「自身の設定基準」「実際の挙動基準」で、それぞれのアクティブ状態を取得することができるわけです。
切り替え時に呼び出される関数がある
非アクティブ・アクティブになった瞬間に処理を行いたいこともあるでしょう。
例えば「アクティブになった瞬間に出現音を鳴らす」とかでしょうか。
そんな時は以下のメソッドを利用しましょう。
OnEnable・・・アクティブになった時に呼ばれる関数
OnDisable・・・非アクティブになった時に呼ばれる関数
実際に使ってみましょう。
使い方は簡単で、Update関数やStart関数と同じように、定義しておけば勝手に呼び出してもらえます。
public class ScriptManager : MonoBehaviour { void Start () { } void OnEnable () { Debug.Log("OnEnable"); } void OnDisable () { Debug.Log("OnDisable"); } }
この辺りの、勝手に呼び出してもらえる関数に関して知りたい人は、公式リファレンスの
「スクリプトライフサイクルフローチャート」の項目に目を通しておくことをお勧めします。
URL:https://docs.unity3d.com/jp/current/Manual/ExecutionOrder.html
非アクティブだとfind関数で探せない!
またアクティブ状態を変更した際に、初心者がはまる問題として、GameObject.Find関数で取得できなくなる問題があります。
この辺りについての詳細は、以下の記事を読んでみてください。
まとめ
今回はsetActive関数をはじめとして、アクティブ状態全般について見てきました。
一時的に動作を止めるという、生成・削除と合わせて、重要な項目の一つなので覚えておきましょう。
それではお付き合いいただきありがとうございました!