(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]

特定のシーンだけ再生出来ないようにする【Unity】【エディタ拡張】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 2018.4.1f1


はじめに

今回は「このシーンは再生はしてほしくない!」みたいなシーンがある場合に

そもそも再生出来ないようにするというちょっとトリッキーな話。


イメージとしては以下のような感じ。

f:id:kan_kikuchi:20190715060906g:plain


ちなみに、「特定のシーンだけ別のシーンから再生されるようにしたい」

という場合は以下の記事を参照のこと。

f:id:kan_kikuchi:20190716080453g:plain


なお、記事中の画像は以下のアセットを使っております。





ScenePlayBlocker

早速ですが、シーンの再生を阻止するクラスScenePlayBlockerのプログラムです。

using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

/// <summary>
/// シーンの再生を阻止するクラス
/// </summary>
[ExecuteInEditMode]//ExecuteInEditModeを付ける事でOnEnableやOnDestroyが再生していなくても実行されるようになる
public class ScenePlayBlocker : MonoBehaviour{
  #if UNITY_EDITOR

  //=================================================================================
  //初期化、破棄
  //=================================================================================
  
  //有効になった時(シーンを開いた時)に実行
  private void OnEnable() {
    EditorApplication.playModeStateChanged += OnChangedPlayMode;
  }

  //削除されたた時(シーンを閉じた時)に実行
  private void OnDestroy() {
    EditorApplication.playModeStateChanged -= OnChangedPlayMode;
  }

  //=================================================================================
  //イベント
  //=================================================================================
  
  //プレイモードが変更された
  private void OnChangedPlayMode(PlayModeStateChange state) {
    //実行ボタンを押した時
    if (state == PlayModeStateChange.ExitingEditMode) {
      //再生を強制的に止める
      EditorApplication.isPlaying = false;
      
      //ログを出して注意もしておく
      Debug.LogWarning("このシーンは再生出来ません!");
    }
  }

  #endif
}


これをシーン内のオブジェクトにAddすると、

f:id:kan_kikuchi:20190715055722j:plain


そのシーンは再生できなくなります。(他のシーンに影響はない)

f:id:kan_kikuchi:20190715060631g:plain


一応、プログラムについて解説をしてみると、以下のような感じでかなり単純です。

  1. ExecuteInEditModeの属性を付けて、OnEnableとOnDestroyを再生してない時にも実行されるように
  2. EditorApplication.playModeStateChangedでプレイモードの変更を検知
  3. 実行ボタンが押されたらEditorApplication.isPlayingをfalseにして再生を止める


ちなみにEditorApplication.playModeStateChangedについては以下の記事を参照の事。



なお、上記の例だと警告を出すようにしていますが、EditorUtility.DisplayDialogを使って、



ウィンドウ出して伝えるのも良いかもしれません。

using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

/// <summary>
/// シーンの再生を阻止するクラス
/// </summary>
[ExecuteInEditMode]//ExecuteInEditModeを付ける事でOnEnableやOnDestroyが再生していなくても実行されるようになる
public class ScenePlayBlocker : MonoBehaviour{
  #if UNITY_EDITOR

  //=================================================================================
  //初期化、破棄
  //=================================================================================
  
  //有効になった時(シーンを開いた時)に実行
  private void OnEnable() {
    EditorApplication.playModeStateChanged += OnChangedPlayMode;
  }

  //削除されたた時(シーンを閉じた時)に実行
  private void OnDestroy() {
    EditorApplication.playModeStateChanged -= OnChangedPlayMode;
  }

  //=================================================================================
  //イベント
  //=================================================================================
  
  //プレイモードが変更された
  private void OnChangedPlayMode(PlayModeStateChange state) {
    //実行ボタンを押した時
    if (state == PlayModeStateChange.ExitingEditMode) {
      //再生を強制的に止める
      EditorApplication.isPlaying = false;
      
      //ウィンドウグを出して注意もしておく
      EditorUtility.DisplayDialog("再生不可シーン", "このシーンは再生出来ません!", "了解!");
    }
  }

  #endif
}
f:id:kan_kikuchi:20190715060906g:plain


ちなみにEditorUtility.DisplayDialogは二択にして、その結果を受け取る事も出来るので、

以下のように絶対に再生させない無限ループを作る事も出来ます。(おそらく使い道はないです)

//一旦、再生を強制的に止める
EditorApplication.isPlaying = false;

//二択を出して、"する"が選択したら再度再生する(が、また上の行で再生が止められる)
EditorApplication.isPlaying = !EditorUtility.DisplayDialog("このシーンは危険です", "本当に再生しますか?", "しない", "する");
f:id:kan_kikuchi:20190718090413g:plain