こんにちは、Unityエンジニアのオオバです。
MonoBehaviour を継承したクラスには、Unityから特定のイベント(以降:イベント関数)を受け取れるようになります。
以下はイベント関数の一部です。
- Awake
- Start
- OnEnable
- Update
これらの関数が実行される条件は GameObjectまたはコンポーネントがアクティブなとき です。
ちなみにアクティブ状態とは👆上のとおり、チェックが入った状態です。
SetActiveとは GameObjectのアクティブ切り替え 、一方enabledは コンポーネントのアクティブ切り替えのこと です。
本記事は SetActiveとenabledどっちを使うべきかの判断基準 について解説していきます。
GameObject
とコンポーネント
はUnity開発の肝。
お互いの特性を理解し、よりよいゲーム設計を目指しましょう。
SetActiveとenabledに悩まされている人は、ぜひ最後まで読んでみてください。
そもそもMonoBehaviourのことがよくわからないという方は次の記事がおすすめです。
Unityのアクティブ切り替えは、可能な限りenabledを使い、SetActiveは使わない
結論から書くと、 やりたいことを実現できるのであれば「enabled」だけで対応すべき です。
理由は SetActiveの負荷が高い からです。
基本的にSetActiveは trueのまま 。
enabledを切り替える という設計が望ましいです。
結論だけ読んでも分かりづらいと思います。GameObjectとコンポーネントの特性の把握が重要。
両者の違いはコチラの記事でわかりやすく解説したのでぜひ読んでみてください。
👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!
- Unityのアクティブ切り替え6パターン
- パターン① GameObject : OFF | コンポーネント : OFF
- パターン② GameObject : ON | コンポーネント : OFF
- パターン③ GameObject : OFF | コンポーネント : ON
- パターン④ GameObject : ON | コンポーネント : ON
- パターン⑤ パターン② → コンポーネント : ON
- パターン⑥ ⑤ → GameObject : OFF → ON
- GameObjectのON / OFFとコルーチンの関係性
- GmaeObjectとコンポーネントのON / OFFから分かること
- ユーザー定義メソッドは常に呼ばれる
- 【例外】 GameObjectがOFFのときコルーチンは実行できない
- Unityアクティブ切り替えまとめ「可能な限りenabledを使う」
Unityのアクティブ切り替え6パターン
アクティブ切り替えによる処理順の把握はとても重要 です。
ここからは SetActive
と enabled
の関係について6パターンに分けて解説します。
パターン① GameObject : OFF | コンポーネント : OFF
- 何も実行しない
パターン② GameObject : ON | コンポーネント : OFF
- Awake
パターン③ GameObject : OFF | コンポーネント : ON
- 何も実行しない
パターン④ GameObject : ON | コンポーネント : ON
- Awake
- OnEnable
- Start
- Update(何度も)
ここまでを表にまとめました。
No | GameObject | コンポーネント | イベント関数(数値は順番) |
---|---|---|---|
1 | OFF | OFF | なし |
2 | ON | OFF | 1.Awake |
3 | OFF | ON | なし |
4 | ON | ON | 1.Awake 2.OnEnable 3.Start 4.Update |
GameObjectがONにならないと何も動かない ということが分かります。
パターン⑤ パターン② → コンポーネント : ON
その2の状態
↓
コンポーネント : ON
- OnEnable
- Start
- Update
Awakeは呼ばれずに、
OnEnable、Start、Updateと呼ばれます。
パターン⑥ ⑤ → GameObject : OFF → ON
その5の状態
↓
GameObject : OFF
↓
GameObject : ON
- OnEnable
- Update
Awake、StartはGameObjectにつき1回だけ呼ばれます。
GameObjectのON / OFFとコルーチンの関係性
コルーチンとGameObjectの関係は切っても切り離せません。
コルーチンとは中断と再開が可能な関数 です。
なぜGameObjectと密な関係なのかというと、
コルーチンはGameObjectがON(アクティブ)のときしか動かない からです。
次の記事ではコルーチンについて徹底解説しました。
コルーチンをあまり理解できていないと感じたらぜひ読んでみてください。
コルーチンはゲーム開発では必須の知識 です。
話を戻します。
次ののコルーチンを実行してみましょう。2つのログを出力するコードです。
IEnumerator Start()
{
Debug.Log("Before Timer");
yield return Timer();
Debug.Log("After Timer");
}
IEnumerator Timer()
{
yield return new WaitForSeconds(1f);
gameObject.SetActive(false);
}
結果は
Before Timer
しか出力されません。 なぜならTimer
メソッド内でGameObjectがOFFになるためです。GameObjectがOFFになると、実行中のコルーチン(Startメソッド)は停止します。
だからDebug.Log("After Timer");
は呼ばれないのです。
GmaeObjectとコンポーネントのON / OFFから分かること
- AwakeはGameObjectがONのときのみ実行
- GameObjectがOFFのときコンポーネントがONになっても何も実行されない
Awake
、Start
はGameObject生成後1度しか実行されないOnEnable
はアクティブの切り替えで何度も実行される- GameObject、コンポーネントをどちらかOFFで
Update
は停止する - コルーチンはGameObjectがONのときしか動かない
ユーザー定義メソッドは常に呼ばれる
ユーザー定義メソッドとは、以下のようなAwake、StartといったUnityが予約していないメソッドです。
public void Hoge(){}
ユーザー定義メソッドはGameObjectやコンポーネントがOFFだったとしても外部から呼ぶことができ、処理は走ります。
GameObject、コンポーネントのON / OFF影響をまったく受けません。
【例外】 GameObjectがOFFのときコルーチンは実行できない
コルーチンは例外です。GameObjectがOFFのコルーチンを実行しようとすると
次のエラーが出力するので注意です。
Coroutine couldn't be started because
the game object 'GameObject名' is inactive!
ここまでを表にしてみます。
No | GameObject | コンポーネント | イベント関数 | コルーチン | ユーザー関数 |
---|---|---|---|---|---|
1 | OFF | OFF | なし | 不可 | 可 |
2 | ON | OFF | 1.Awake | 可 | 可 |
3 | OFF | ON | なし | 不可 | 可 |
4 | ON | ON | 1.Awake 2.OnEnable 3.Start 4.Update | 可 | 可 |
- アクティブのON/OFFでユーザー定義メソッドの呼び出しは制御不可
- Unityのイベント制御をベースにON / OFFを判断するべき
- GameObjectをOFFにするとコルーチンが止まるので注意
ここからGameObject、コンポーネントの
ON/OFF判断の基準について考察します。
結局SetActiveとenabledどっちを使えばよいのかまとめます。
Unityアクティブ切り替えまとめ「可能な限りenabledを使う」
最初の結論でも書きましたが SetActiveは負荷が高い ため やりたいことが実現できるならenabledだけを使うです。
コルーチンを止めたいのであれば、 StopCoroutine
を使いましょう。
負荷がかかっても問題ないタイミングどうしてもな場合に限ってSetActiveは許容です。
メインはコンポーネントのenabledを切り替える設計が良い でしょう。
ただしコンポーネントのON/OFFを切り替えるのは正直面倒くさいです。1つのGameObjectにいくつも複数のコンポーネントがくっついていますからね。
管理的にすごく複雑になりSetActiveのON/OFFでシンプルで安全な設計になるのであれば SetActiveを優先する判断もあり です。
enabled優先論はあくまパフォーマンスにおける理想論です。
ケースバイケースで総合的に判断しましょう。
この記事が気に入ったらフォローしよう
「Unity初心者大学」というUnity初心者向けのYouTube始めました!!
ぜひチャンネル登録をお願いします!
最後まで読んでいただきありがとうございました!
すばらしいUnityライフをお過ごしください。
- Unity2020.3.19f1