クラゲ日記スマートフォン用の表示で見るクラゲ日記UnityのTipsなど技術関連がメイン。この広告は、90日以上更新していないブログに表示しています。2015-11-08【Unity】SerializeFieldなキャッシュ変数をビルド前にキャッシュするこんにちは。パネルの中に複数のボタンが置かれるUIなど特にそうですが、Sceneに配置する個々のオブジェクトが階層化されていくことがあります。いう場合、UIパネル内のボタン文字列をメニュー選択項目に合わせて変更する場合など階層下の子に何度もアクセスする場合が多くなります。取得するのは無駄ということで、変数をキャッシュするモチベーションが生まれるわけです。"Button2"という2つのボタンをもつUIパネルオブジェクトを制御するスクリプト(HogePanel)を考えると、こんな感じにAwake();でキャッシュを初期化するのが一般的かと思います。}...}これはこれで悪くないのですが、ビルド前から分かっている参照対象ならビルド前に初期化出来るはずです。いうことで次のような方法を試してみました。SerializeFieldに出来るものならなんでもOKといったところです。継承されるオレオレMonoBehaviourクラス(以前の記事のTransCacheBehaviourの改良です)です。Scene中のキャッシュ変数を全て初期化しなおすためのEditor拡張クラスです。ショートカットキーを作ってキャッシュをしなおすようにしておきます。}...}かなりシンプルですが、準備のクラスは以上2つです(MyCommonEditorWindowはAssets/Editor以下に入れないとダメかも)。}...}こうなります。refleshed."と表示されシーン中のオブジェクトのキャッシュが初期化されます。Awake();でのキャッシュ初期化も、正直大したコストではないとは思いますが、数が増えればバカには出来ませんし、出来るんだからビルド前にやっておこうか、という感じでした。...注意点としては、うっかり[SerializeField]を付け忘れるとログも正しく表示されるのに実行時はnullになっていることです。一度慣れればミスしても症状からすぐ想像が付くようになるのですが......。01:20【Unity】SerializeFieldなキャッシュ変数をビルド前にキャッシュするTweet広告を非表示にするもっと読むコメントを書く2015-07-28steamデビューしました!星追いの巫女こんばんは。ブログを放置気味のけっとです。playismとsteamで販売開始しました。去年の夏に頒布した同作は、「作ったもんがちだ!」的精神のもと、プログラミング、モデリングなどボリュ~ミィ~な作業を人間性を捨てた進捗マシーンのごとく強引に推し進めた末の完成ということもあり、単にリーダーだったということ以上に思い入れが強い作品です。その流れ(?)で、販売はあくまでノンリニアからですが、販売に伴う作業は結局全部自分でやってしまいました。翻訳リストの作成、翻訳済み英文の組み込み、ゲームプログラムの多言語対応、ええと、あとはsteamの実績・トレカ・バッジ・壁紙のデザイン・実装・素材作り......こうして見ると一言で言えばただの翻訳移植でも結構いろいろありましたね......。大変だったなぁ......(遠い目)。そのかいあってこうして無事に両サイトで販売が開始されて、晴れてsteamクリエイター(?)になることが出来ました!今までほそぼそと作っていた身としては、あれだけ大きい場で作品を扱ってもらえるというのは本当にウレシイものです。steamの市場でゲームがどんな評価を受けるかはわかりませんがとりあえず一つステップを登れたのかなと思いつつ、これからもいっしょうけんめいゲームを作っていきたいなと思います。今後ともよろしくお願いします。UI結果のメモのようなものです。百万回くらいやられていそうなTransformのキャッシングの比較をしました。テストのモチベーション構造化を考えてUIを作っていると、パネルという概念があることに気付きます。RPGのパーティのステータスを表示するということを考えると、例えばUnity+NGUIならこんな感じになるでしょう。これをコードから制御します。classを実装してUIを制御するならパネル1種類に1classくらいが適当でしょう。すると、例えばこんな感じになります。遅そうですが、大抵の場合はこれで十分です。呼ばれますが、それでも1秒に一回程度ならそこまで問題にはなりません。毎フレームに近いレベルになるとちょっと不安です。それに近いことが起こりそうだったので調査してみた次第です。テストの問題設定classから実行中に変化しない相対パスを持つ100個の子Transformに繰り返しランダムアクセスを行う各キャッシュ方式でのアクセス速度の比較。方式によってはキャッシュを実装するコストがバカにならないので、必ずしも速ければいいというものではありません。}...}テストコードの全文は最後に。全コピペでどこかにAddComponentして実行すればAキーで実行出来ると思います。試したのは、流石にintリテラルを前提には出来ないからです。普通のintアクセスと比べると一応遅くはなってますが問題ないでしょう。cacheはindexes[]へのintランダムアクセス分他より速くなっています。FindChildも個人的には予想通りというか、全然いいじゃんというレベルでした。キャッシュ用基底クラスを作ってみるでは実際に、キャッシュを使う場合の基底用オレオレBehaviourクラスを作ると、こんな感じかなと思います。}}使い方としてはこうなります。}...}eCacheChilds.HPLabel.ToString()の結果は"HPLabel"になるのでCACHE_PATHはコードの重複になりますが、enumのToStringは非常に遅いので注意が必要です。そのほかテストの目的は以上で達成出来たかなと思いますが、得られたその他の知見をいくつか挙げてみます。FindChild??速度同じやん......。要はFindChildがFindのラッパですね。理屈上はFindの方が僅かに速いんでしょう。遅い?風の噂で聞いたのでついでに。FindChild()のオーバーヘッドに比べれば気にならないくらいですね。Qiitaによるとやはり速いには速いようなので、オレオレMonoBehaviourを作るならついでにキャッシュしておいてもいいかもしれません。Transform>はいいやつだったよ...これが使える速さならキャッシュの下準備がラクになると思ったのですが、キャッシュする価値はないレベルですね......。FindChildがオマケのついたルックアップみたいなもんだろうとたかをくくっていたら、思ったより速いんですね。ランダムアクセスListのランダムアクセス、Arrayと同じだと思っていたら、倍も遅いんですね。何かオマケの処理でも入ってるんでしょうか。以下、テストコードの全文です。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。