Assetsゲームブログお問い合わせUnityでシーンの実行中にスクリプトを編集するとちゃんと動かないことがあるわけUnityではイベント毎に各オブジェクトにメッセージが飛んで、そのメッセージを処理することでオブジェクトが動作するしくみになっている。いうイベントがどういう順番で起こるかを知っておくことはとても重要。その辺のことはちゃんとマニュアルに書いてある。ここで書いておきたいことは、スクリプトがビルドされた後にどんなイベントが起こるのかということ。いうのも、スクリプトを編集した後にUnityに戻ると、シーンを実行中だったりExecuteInEditMode属性のついたスクリプトがあったりするとおかしなことになることが頻繁にあるからだ。OnEnableStartUpdate:さて、以上が調べた結果なのだが、ここでのポイントは、スクリプトがビルドされた後は静的コンストラクタやコンストラクタがもう一度呼ばれるということ。それなのに、AwakeやStartは呼ばれない(まあ呼ばれても困るんだけどね)。AwakeやStartで初期化をしている場合(普通はそうすると思うけど)、問題が起こる場合がある。言っても、大抵の場合は大丈夫。シリアライズの対象ではないメンバ変数なんかもきちんと復元されていたので、問題が起こるのは以下のような場合。静的メンバ変数をAwakeやStartで初期化している場合シングルトンの場合なんかはこれをやっていることが多いと思うけど、そうするとスクリプトがビルドされた後にインスタンスを参照してた静的メンバ変数がnullになっちゃう。他には、僕の場合はシェーダーのプロパティIDを静的メンバ変数にしていて、AwakeのときにShader.PropertyToIDで静的メンバ変数に値を保存していたのだけど、これらが静的コンストラクタで全部0になっちゃうのでシェーダー定数のセットがちゃんとできなくなる。シリアライズ可能ではないメンバ変数を使っている場合スクリプトがビルドされた後でも復元される変数というのはシリアライズ可能な変数に限られるようだ。実際にシリアライズの対象になっているかどうかは関係ない。シリアライズ可能でさえあればprivateなメンバ変数もちゃんと復元される。Dictionary<T,T>なんかよく使うと思うのだけど、これはスクリプトがリビルドされると無惨にもクリアされてしまう。これがList<T>だと大丈夫。自分で作ったObjectではないクラスなんかもSystem.Serializable属性をつけておかないと復元されない。対策Dictionaryとかがクリアされちゃうと辛いものがあるけど、とれる対策としてはOnValidateを使うこと。これはインスペクタなどでプロパティが編集されたときに呼ばれるもので、Editor上でしか呼ばれない。この関数で再初期化できるものはしてしまう。他にOnEnableとOnDisableを使うという手もある。Awakeは呼ばれないけどこれらは呼ばれるので、再初期化をOnEnableでして、後始末をOnDisableでするようにすると、とても行儀の良いオブジェクトになると思う。変数が参照されるときにnullだったら初期化するというようなコードにしておけば、こういう問題は起きなくなる。UNITY_EDITORをつける。シングルトンのポインタなんかはコンストラクタで初期化しても良い。コメントをキャンセルメールアドレスが公開されることはありません。経験豊富なプログラマーがお手伝いします。デバッグや最適化など短期間のものでも長期のお手伝いでも、リモートでできることであれば何でもお問い合わせフォーム(もしくはメール)でお気軽にご相談ください。ランニングブログ始めましたプログラミングは体力勝負!それにいつも頭を使って疲れます。ランニングで体力をつけつつ、頭をリラックスさせてストレス発散すれば、仕事の効率もはかどるというもの。そんなわけでランニングを始めたのですが、ついついハマってしまい、ブログも始めました。よろしければこちらもどうぞ。WordPressEnglish。