テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

Unity 5、プリオーダー向けにベータ版を提供開始


Unity 5.0 pre-order beta now available! – Unity Blog

 

Unity5がプリオーダー向けに提供を開始しました。

Unity 5のライセンス(2014年3月20日以降に購入したライセンス)でアクティベートする事で使用可能になるみたいです。

 

Unity5のダウンロードサイトはこちら。

Unity - Beta - Unity 5.0

Unityのシーン上に配置したモデルを結合する

f:id:tsubaki_t1:20141025014524p:plain

 

以前、ステージの作り方について紹介しましたが、これには想像の通り問題が一つあります。それは、GameObjectをすごい数要求する事です。

 


Sample Assetsのプロトタイプアセットを並べて簡単なステージを作ってみよう[Unity] - テラシュールブログ

 

Unityにおいて初期化時に問題になる項目は3つ、シェーダーのコンパイル、リソースのエンジン登録、GameObjectの構築です。ゲームが本格化するとシリアライズの高速化や別スレッドに逃す事も含まれます。さらに言えば、参照の結合をランタイムで実行してるとコレも問題になりやすいのですが、それは取り敢えず置いておきます。

 

大量にGameObjectがあるとGameObjectの構築に時間がかかるため、以前紹介した方法でステージを作成すると少し問題となります。Unityのレンダラーは1つのモデルにつき1つのGameObjectを要求するため、ステージを作成するにつれGameObjectの数が膨大になる可能性があり、そこに高いコストの可能性が出てきます。

下の画像は約600個のGameObjectを使用したステージです。

 

f:id:tsubaki_t1:20141024211617p:plain

 

この回避方法は2つ。一つは「動的に構築する」事、もう一つは「事前に結合してしまう事」です。

 

動的に生成する方法は、事前にステージ構造を取得しておき、「見える部分」を表示するために使用するGameObjectを生成する方式です。Resourcesから非同期でインスタンス化するを「段階的に全部」行う事で、初期コストを何とかします。

これを実現するには、オブジェクトを動的に構築できるエディタ拡張を事前に行っておくか、全てのオブジェクトを別途プレハブにして構築するような設計が必要になります。

 


Resourcesから非同期でインスタンス化する - テラシュールブログ

 

もう一つは、メッシュを結合してしまい1つのGameObjectでレンダリング可能にしてしまう方法です。そのためにCombineMeshesを使用します。

CombineMeshesの基本的な使い方 - Neareal

 


MeshCombiner.cs

上のサイトを元に、マテリアルが複数あればその分だけメッシュを分割するコードを作成しました。メッシュの親に本コンポーネントをアタッチし、コンポーネントコンテキストメニューから「Export」を選択すると、新しくメッシュが作成されます。

その際元のオブジェクトにEditorOnly(ビルド時シーンから削除されるタグ)が付与され、Activeがfalseになります。

f:id:tsubaki_t1:20141024214728p:plain

 

CombineMeshesを使用してメッシュを結合したのが下の図です。600オブジェクトが3オブジェクトまで縮小しています。また、ドローコールも削減されます。

 

f:id:tsubaki_t1:20141024210148p:plain

一度統合したメッシュを再調整したい場合は、先ほどActive=falseになったオブジェクトにチェックを入れて再表示します。そうすると結合したオブジェクトが非表示になり、編集可能となります。

 

この方法の一つの問題点は、モデル分のアセットが作成される事です。一つ一つのサイズはテクスチャと比べてカスみたいなサイズですが、量が増えてくると少々厄介かもしれません。なので、やはりある程度使いまわす事を前提とした設計が必要になります。

 

また、あまりにサイズが大きいメッシュを作るのは良くない気がします。単純に超量の多いモデルは失敗しますし、GPUのメモリを使い果たしてしまうような巨大なオブジェクトは何というか良くないです。画面外判定の事もありますし。

 

またBox Colliderが全て剥がれるので、MeshColliderで当たり判定を作らないと抜けます。

 


ドローコールを減らす!Draw Call Minimizer - テラシュールブログ


Draw Call Minimizerの使い方と問題について - テラシュールブログ

 

で、この機能と概ね同じ事をしているのが、以前に紹介したDraw Call Minimizerです。このアセットは、メッシュとマテリアルを結合して一つにします。最近は事前にモデルを変換(しかもOBJに)出来るようになったので、割と使い勝手が良いかもしれません。テクスチャの統合は正直今の環境では邪魔なので、切る方法を聞いてみようと思います。

 

車輪を再開発した後に調べたら自分のブログが見つかっちゃうってのは悲しいような嬉しいような…

 

MacでUnityのウィンドウが表示されない時の対処法

Macで作業を行っていると、画面外にアプリのウィンドウが行ってしまい戻ってこないケースが稀にあります。

 


Macで画面外にウィンドウが飛んでっちゃった時の対処法 - 量子化された無意味な人生

 

基本的にはMacのウィンドウ管理機能が云々しているので、概ねPreferencesのファイルを全部消せばなんとかなるのですが、Unityの場合これで上手くいかない場合があります。

 

というのも、Unityのウィンドウ配置はMacとは別にもっているため、この手法で復旧できない可能性があります。

 

そんな場合、Libraryを消しましょう。それで治る場合があります。

もしくはLibraryのCurrentLayout.dwltを他の正常なプロジェクトから引っこ抜いて上書きすれば、開けるようになる場合があります。

 

要するにCurrentLayout.dwltに現時点(画面外に行って戻ってこない)のレイアウトが格納されているっぽいので、これを何とかしようって作戦です。

Unityエディタのクラッシュ時に失われたシーン情報を復旧させる裏ワザ

Unity5.3以降の場合はこちら

tsubakit1.hateblo.jp

 

5.3以前の場合は以下の記事をどうぞ(5.3以降でも理屈は同様です。理屈を知りたい場合はどうぞ)

 

 

 

例えばUnityエディタで無限ループを行う処理を書いている場合、Unityはクラッシュします。その際、シーンを保存していなければ作業中の内容は失われる事になります。

 

そうならない為に、一定時間ごとにバックアップを取ってくれるAutoSave等のアセットがあれば安心ではあるのですが、入れていないケースもあります。


Unityに自動セーブ機能を追加してみた - テラシュールブログ

 

さて、このクラッシュ、状況が「ゲーム再生時に発生した」で「エディタで再度開いていない」のであれば、実は復旧出来る可能性があります。

 

クラッシュ時に失われたシーン情報を復活させる

クラッシュした際のシーン復旧手順は以下のとおりです。

ただし一度でもクラッシュ後にUnityでクラッシュしたプロジェクトを開いてしまうと、復旧出来ません。クラッシュ直後でUnityを開いていないことが重要です。

 

  1. クラッシュした際の「Temp/__EditModeScene」をAssets以下に移動させます。
  2. 名前を「__EditModeScene.unity」とかにします。
  3. 「__EditModeScene.unity」を開きます

 

f:id:tsubaki_t1:20141020224300p:plain

開くと最後に開いていたシーンが表示されるはずです。後はオブジェクトをコピー&ペーストで本来のシーンへ移動するなり。もしくは、既存のシーンを__EditModeSceneファイルで上書きするのも良いかもしれません。

 

原理

実は__EditModeSceneにはシーン再生直前のシーン情報が格納されています。何故そんな事をしているかと言えば単純で、「シーンの再生を停止させた時に戻す」為です。

 

たとえばシーン再生中に__EditModeSceneを違うファイルで上書きすると、再生終了時に全く違うシーンに戻ります。この事から、この__EditModeSceneを元シーンに上書きもしくは開いてやる事で、クラッシュする直前のシーンを開く事が出来る訳です。

 

ここで問題となるのは、TempフォルダはUnityエディタを起動した際に一旦全削除される事です。再三エディタ開く前と言ってるのはこのためです。もしUnityエディタを開き__EditModeSceneを失った場合は、もう戻せません

なので、この機能は最後の手段として、やっぱり定期的にシーンをセーブすることが安定かなと思います。シーンは復旧出来てもプレハブはバックアップされてないので…。

ちなみにプレハブやAnimatorの情報は保存はFile>Save Projectで出来るみたいです。

 

 

AutoSaveエディタ拡張、この原理を利用したバージョンに修正中です。Unityモジュールとして(Assets以下を汚す事なく)クラッシュ時にもボタン一発で復旧出来るような感じにできないか調整中