UnityEditor再生開始時のイベント取得
UnityEditor再生時のイベント
実行、非実行時でモデルプレビュー出来るツールを作成しているのですが、再生時にモデルを一旦リセットして再生成するスクリプトを作成したい
ということでこんなスクリプトを書くと
ここのボタンを押す度にOnPlayModeStateChanged
メソッドが呼ばれるようになります
void OnEnable () { EditorApplication.playmodeStateChanged += OnPlayModeStateChanged; } void OnDisable () { EditorApplication.playmodeStateChanged -= OnPlayModeStateChanged; } void OnPlayModeStateChanged () { Debug.Log("Changed"); }
ここで問題なのが思っているよりも多くこのイベントが発行されるということです しかし、このメソッド内で
EditorApplication.isPlaying
EditorApplication.isPlayingOrWillChangePlaymode
の値を見るとより詳細なStateが確認できます
- 再生ボタン押下
- OnChanged : isPlaying=false, isPlayingOrWillChangePlaymode=true ※このタイミングで生成すると実行開始時にCleanupエラーが出る
- 開始するまで少し待つあれ 実行ログ出力開始
- OnChanged : isPlaying=true, isPlayingOrWillChangePlaymode=true ※実行開始、生成すると通常通り動作する
- 停止ボタン押下
- OnChanged : isPlaying=true, isPlayingOrWillChangePlaymode=false ※停止開始、生成するとあれ
- 完全停止待つ
- OnChanged : isPlaying=false, isPlayingOrWillChangePlaymode=false ※完全停止Editorの挙動開始
つまりisPlaying==isPlayingOrWillChangePlaymodeを見ることで実行、Editorに完全移行したかどうかが取れ、逆の場合は遷移する直前の処理が書けます
このままだとPauseボタンでも呼ばれてしまうので上記の条件が一致したらフラグを立てておくことでPauseを無視することができます でもOnDisableとOnEnableだけで上手く頑張れば出来るっぽい雰囲気 とりあえずこのプロパティと組み合わせれば厳密にStateを取れたという感じ
Unity5.3でExecuteInEditModeとDontDestroyOnLoadを同時に使用した際の挙動
Unity5.3にアップデートしてかなり発見しにくいバグ?を見つけたのでメモ
問題
[ExecuteInEditMode] public class Test : MonoBehaviour { void Awake() { DontDestroyOnLoad (gameObject); } }
こんなクラスがあった時にEditor上でHierarchyにスクリプトを追加しようとすると表示されず、GameObject毎どこかに行ってしまいます。
FindObjectOfType
を使用するとどこかに存在していることは分かるのですが、困ったことにどこにも見つかりません。
原因
原因はDontDestroyOnLoadの挙動が変更されているからのようです。 このメソッドが呼び出された直後、普段は隠蔽されている”DontDestroyOnLoad”シーンにGameObjectが移動される挙動になっていました。
gameObject.scene.name
でログを出力するとDontDestroyOnLoadシーンに飛ばされていることが分かります。
このシーンは実行直前にHierarchy上で確認することが出来ます。
(実行が開始すると消えるので動画キャプチャから抜き出しました)
解決策
解決策としては実行している時のみ指定をすれば一応動作します
if (Application.isPlaying) { DontDestroyOnLoad (gameObject); }
滅茶苦茶ハマりました…
ScriptableObjectのメンバリネーム
ScriptableObjectを使用している時に変数定義を変えたくなることがあると思います。
例えばpublicで定義していたけどやはりprivateのSerializeFieldにしてスクリプトからは読み込み専用にしたくなった等
その時は
[System.Serializable] public class Data { [SerializeField] [UnityEngine.Serialization.FormerlySerializedAs ("name")] private string _name; }
これで変数名の移行が行われます。
この状態でプロジェクトの保存を行うと_nameに値が移行されていることを確認することが出来ます。
全ての関連ファイルの変更が行われたことを確認できたらFormerlySerializedAs属性は消しても大丈夫です。
※これに限らないですがPrefabと同じようにSaveProjectを実行しないと見た目は差し替わっていてもファイルに書き込まれていないため、書き込まれていることを確認してから属性削除は行う必要があります。
ターゲットの周りをくるくる回るサンプル
なんとなく作ったので記事にします
gist.github.com
ターゲットの周りを常に一定間隔で回るサンプルです。カメラのコンポーネントに付けてみてください
クォータニオン先輩使えば回転量定義できて座標変換が簡単に実装できます。
UnityEditorのObjectFieldでフォルダのみ入れる
もっと簡単な方法あれば教えて下さい><
Object folder; var newFolder = EditorGUILayout.ObjectField (folder, typeof(Object), false); var path = AssetDatabase.GetAssetPath (newFolder); if (AssetDatabase.IsValidFolder (path)) { folder = newFolder; } else { folder = null; }
どこかにありそうですが、パッと見つからず、試しにそれっぽく使ってみたら上手く行ったのでメモとして残しました。
AssetBundleメモ
Unity5.1.0での話
- AssetBundle.CreateFromFileはエラーになって動かない
- ビルド時は出力フォルダの.manifestファイルを参照しているためファイルをリネームすると再ビルドが走る
- AssetBundle本体のファイルが存在しているかどうかのチェックはされていないのでリネームしても可
- AppendHashフラグを持たせるとファイル名の後にハッシュ値が付与されたファイル名になる。