渋谷ほととぎす通信

「Unityをわかりやすく」初心者のためのゲーム作りブログ

【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ

【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ

こんにちは、Unityエンジニアのオオバです。

お悩みさん
お悩みさん
  • SetActiveとenabledって似ててよくわからない
  • どういうケースでどちらを使うべき?
  • オオバ
    オオバ
    本記事ではこれらの悩みを解決します。

    MonoBehaviour を継承したクラスには、Unityから特定のイベント(以降:イベント関数)を受け取れるようになります。

    以下はイベント関数の一部です。

    • Awake
    • Start
    • OnEnable
    • Update

    これらの関数が実行される条件は GameObjectまたはコンポーネントがアクティブなとき です。

    ※メソッドによって条件は違います

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_0

    ちなみにアクティブ状態とは👆上のとおり、チェックが入った状態です。

    SetActiveとは GameObjectのアクティブ切り替え 、一方enabledは コンポーネントのアクティブ切り替えのこと です。

    本記事は SetActiveとenabledどっちを使うべきかの判断基準 について解説していきます。

    GameObjectコンポーネントUnity開発の肝
    お互いの特性を理解し、よりよいゲーム設計を目指しましょう。

    SetActiveとenabledに悩まされている人は、ぜひ最後まで読んでみてください。

    そもそもMonoBehaviourのことがよくわからないという方は次の記事がおすすめです。

    Unityのアクティブ切り替えは、可能な限りenabledを使い、SetActiveは使わない

    結論から書くと、 やりたいことを実現できるのであれば「enabled」だけで対応すべき です。
    理由は SetActiveの負荷が高い からです。

    基本的にSetActiveは trueのまま
    enabledを切り替える という設計が望ましいです。


    結論だけ読んでも分かりづらいと思います。GameObjectとコンポーネントの特性の把握が重要。
    両者の違いはコチラの記事でわかりやすく解説したのでぜひ読んでみてください。

    👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!

    Unityのアクティブ切り替え6パターン

    アクティブ切り替えによる処理順の把握はとても重要 です。

    ※以降はアクティブのことを「ON」、非アクティブを 「OFF」というキーワードで解説します。

    ここからは SetActiveenabled の関係について6パターンに分けて解説します。

    パターン① GameObject : OFF | コンポーネント : OFF

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_1

    実行したイベント関数
    • 何も実行しない

    パターン② GameObject : ON | コンポーネント : OFF

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_2

    実行したイベント関数
    1. Awake

    パターン③ GameObject : OFF | コンポーネント : ON

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_3

    実行したイベント関数
    • 何も実行しない

    パターン④ GameObject : ON | コンポーネント : ON

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_4

    実行したイベント関数
    1. Awake
    2. OnEnable
    3. Start
    4. Update(何度も)

    ここまでを表にまとめました。

    NoGameObjectコンポーネントイベント関数(数値は順番)
    1OFFOFFなし
    2ONOFF1.Awake
    3OFFONなし
    4ONON1.Awake
    2.OnEnable
    3.Start
    4.Update

    GameObjectがONにならないと何も動かない ということが分かります。

    パターン⑤ パターン② → コンポーネント : ON

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_5

    その2の状態

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_6

    コンポーネント : ON

    実行したイベント関数
    1. OnEnable
    2. Start
    3. Update

    Awakeは呼ばれずに、
    OnEnable、Start、Updateと呼ばれます。

    パターン⑥ ⑤ → GameObject : OFF → ON

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_7

    その5の状態

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_8

    GameObject : OFF

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_9

    GameObject : ON

    実行したイベント関数
    1. OnEnable
    2. 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);  
    }
    

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_10

    結果はBefore Timerしか出力されません。

    なぜならTimerメソッド内でGameObjectがOFFになるためです。GameObjectがOFFになると、実行中のコルーチン(Startメソッド)は停止します。

    だからDebug.Log("After Timer");は呼ばれないのです。

    GmaeObjectとコンポーネントのON / OFFから分かること

    • AwakeはGameObjectがONのときのみ実行
    • GameObjectがOFFのときコンポーネントがONになっても何も実行されない
    • AwakeStartはGameObject生成後1度しか実行されない
    • OnEnableはアクティブの切り替えで何度も実行される
    • GameObject、コンポーネントをどちらかOFFでUpdateは停止する
    • コルーチンはGameObjectがONのときしか動かない

    ユーザー定義メソッドは常に呼ばれる

    ユーザー定義メソッドとは、以下のようなAwake、StartといったUnityが予約していないメソッドです。

    public void Hoge(){}  
    

    ユーザー定義メソッドはGameObjectやコンポーネントがOFFだったとしても外部から呼ぶことができ、処理は走ります。
    GameObject、コンポーネントのON / OFF影響をまったく受けません。

    【例外】 GameObjectがOFFのときコルーチンは実行できない

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_11

    コルーチンは例外です。GameObjectがOFFのコルーチンを実行しようとすると
    次のエラーが出力するので注意です。

    Coroutine couldn't be started because  
    the game object 'GameObject名' is inactive!  
    

    ここまでを表にしてみます。

    NoGameObjectコンポーネントイベント関数コルーチンユーザー関数
    1OFFOFFなし不可
    2ONOFF1.Awake
    3OFFONなし不可
    4ONON1.Awake
    2.OnEnable
    3.Start
    4.Update
    この結果から分かること
    • アクティブのON/OFFでユーザー定義メソッドの呼び出しは制御不可
    • Unityのイベント制御をベースにON / OFFを判断するべき
    • GameObjectをOFFにするとコルーチンが止まるので注意

    ここからGameObject、コンポーネントの
    ON/OFF判断の基準について考察します。

    結局SetActiveとenabledどっちを使えばよいのかまとめます。

    Unityアクティブ切り替えまとめ「可能な限りenabledを使う」

    【2023年版】UnityのSetActiveとenabledの違い、どちらを使うべきかのまとめ_12

    最初の結論でも書きましたが SetActiveは負荷が高い ため やりたいことが実現できるならenabledだけを使うです。

    コルーチンを止めたいのであれば、 StopCoroutineを使いましょう。

    負荷がかかっても問題ないタイミングどうしてもな場合に限ってSetActiveは許容です。

    メインはコンポーネントのenabledを切り替える設計が良い でしょう。

    ただしコンポーネントのON/OFFを切り替えるのは正直面倒くさいです。1つのGameObjectにいくつも複数のコンポーネントがくっついていますからね。

    管理的にすごく複雑になりSetActiveのON/OFFでシンプルで安全な設計になるのであれば SetActiveを優先する判断もあり です。

    enabled優先論はあくまパフォーマンスにおける理想論です。
    ケースバイケースで総合的に判断しましょう。

    「Unity初心者大学」というUnity初心者向けのYouTube始めました!!
    ぜひチャンネル登録をお願いします!

    最後まで読んでいただきありがとうございました!
    すばらしいUnityライフをお過ごしください。

    オススメ記事
    検証環境
    • Unity2020.3.19f1