テラシュールブログ

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

【Unity】コンパイルが通りエラーも表示されずゲームも実行可能なのに、処理が実行されない

少し面白い挙動に出会ったのでメモ。

 

スクリプトエラーが無いのに処理が実行されない

少し面白い挙動に出会いました。

下のようにビルドは通っておりエラーも特に無く、ゲームを再生出来るのですが、実行時に新しく記述した処理が反映されませんでした

また実行時にThe associated script can not be loaded. Please fix any compile errors and assign a valid script.(スクリプトロード出来ませんでした。コンパイルエラーを修正し、有効なスクリプトを割り当てて下さい)と表示されます。

f:id:tsubaki_t1:20161006225319j:plain

f:id:tsubaki_t1:20161006225324j:plain

 

また、The referenced script on this Behaviour is missing!The referenced script on this Behaviour (任意のGameObject) is missing!といったWarningも表示されます。
はてさて。

f:id:tsubaki_t1:20161006232318j:plain

 

コンポーネント名とクラス名が一致していなかった

よく確認すると、コンポーネント名とクラス名が不一致なだけでした。
UnityはMonobehaviourを使用する場合、クラス名とソースコード名が一致してる必要があるのですが、コンポーネント登録後にクラス名を変更したため、こんな感じになっていました。

f:id:tsubaki_t1:20161006230240j:plain

 

一応今まで通り、新しくコンポーネントを登録する際にはエラーが表示されるのですが、既に登録してあった場合は少し分かりにくい挙動です。

f:id:tsubaki_t1:20161006230542j:plain

 

Unity 5.5のユニークな挙動

そういえばUnity 5.5からか、(バグかもしれませんが)「ファイル内にファイル名と一致するMonobehaviourがあれば、該当するMonobehaviourを動かす」という挙動を行うみたいです。凄く分かりにくい。

f:id:tsubaki_t1:20161006231235j:plain

 

メモ

今回の記事を書いていて思い出したのですが、Betaにてシリアライズしたスクリプトのパラメータを安全に更新する仕組みを作ってるみたいです。

https://forum.unity3d.com/threads/script-data-upgrade.427767/

Over the course of a project, it is very common that the design of code will change, particularly with regards to persistent data. Fields will be added, removed, renamed; they will change type; they will change meaning, such as changing the units they are representing. Making these changes in the middle of a live project, where there is a substantial amount of content already using the existing data layouts, can be challenging.

The Script Data Upgrade feature provides a way to make structured, safe, on-demand changes to your stored data, so you can smoothly bring your created content along as you iterate on your data structures.

 

関連

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

【Unity】.NET 4.6、C# 6対応のUnityエディタ、ベータ版が公開

f:id:tsubaki_t1:20161005215354j:plain

.NET 4.6、C# 6に対応したUnityエディタが公開されてました。

確か7月頃にmonoのバージョンだけ上げて、今回.NET 4.6とC#6に対応したバージョンが公開された感じになります。

 

インストーラーは以下のフォーラムより入手出来ます。

https://forum.unity3d.com/threads/upgraded-mono-net-in-editor-on-5-5-0b4.433541/

 

  • 現状はエディタ機能のみの提供みたいです。
  • SGen GCは.NET 4.6が安定したら搭載するみたいです。
  • ランタイムは初期設定は.NET 2.0が指定されるので、変更する必要があります。

関連

ufcpp.net

【Unity】アセットのUnloadとDestroyについて

今回はアセットのUnloadとDestroyの使い分けと、アセットの運用についてです。

 

基本的にはアセットの開放はResources.Unloadで可能

Resources.Unloadはアセットを開放する事が出来ます。このアセットとは、例えばProfilerのMemoryの項目でAssetsと表示される項目が該当します。

f:id:tsubaki_t1:20161002225917j:plain

Resources.Unloadはソコソコ強力で、Projectビューでアセットと認識している物は大体開放することが出来ます。

 

Resources.Unloadで開放出来ないケース

それ以外の項目、NotSavedやSceneMemoryに格納される、インスタンス化したオブジェクト群はResources.Unloadでは開放する事が出来ません。これは、実行時に値を変更したMeshやMaterialや動的に生成したTexture、Prefab等が該当します。

f:id:tsubaki_t1:20161002230420j:plain

 

また、アンロードされたリソースはUnityのリソースマネージャーから開放され、「Instance IDが再度アクセスするまで」破棄されます。つまり、解放後即座にアクセスされた場合開放されていないように見えます

Instance IDが再度アクセスするまで破棄するとは、少し表現が難しいのですが、Resources.Unloadが破棄するのは、あくまでInstance IDが参照するアセットなので、再度アセットに対して読込が走れば、表示されます。このため、Resourcesが複数の場所から参照されていた場合、まるで破棄されないような挙動になります(実際には破棄され、再読込が走るっぽいです)

この挙動は、ResourcesからTextureを読み込み後破棄、RawImageをEnable/disableすると確認出来ます。

f:id:tsubaki_t1:20161002225051g:plain

 

なお、Unloadが開放するのは指定したアセットのみです。
つまり、Materialを開放したからと言って、Materialが参照するテクスチャ群を開放する訳ではありませんし、Materialが参照するShaderは開放されません。

同様にSpriteをUnloadしたからと言って、Textureを開放してくれる訳ではありません。

 

インスタンス化したアセットの開放はDestroy

NotSavedやSceneMemoryの項目に格納される、インスタンス化したアセットに関しては、Destroyで開放します。


もしエディタで動作させる場合、DestroyImmediate(オブジェクト, true)が必要になるかもしれません。但し、この処理はエディタで動かした場合「ファイルを消す」ので、実際に使用する場合には注意が必要です。(正確には、SetDirtyするまで消えないっぽいですが)

f:id:tsubaki_t1:20161002231905j:plain

 

大抵の場合はUnloadUnusedAssets

パフォーマンス的に問題が無いのであれば、Resources.UnloadUnusedAssetsをとりあえず使っておけば問題は無いはずです。
このメソッドを実行すると、「未使用な」アセットを開放します。

 

この「未使用な」というのが少し曲者で、static fieldやfield等から参照している等の他に、インスタンス化する前のPrefab等から参照していた場合も「使用中」とマークされます。そのため、インスタンス化したGameObjectを破棄した後も、Prefabが残っている場合は参照するアセットが開放されないといったケースは有りえます。

またマニュアルに依るとスクリプト実行スタックは確認していないらしく、アセットを破棄後に再ロードが走るので、開放されないように見えるどころか、余計な負荷が走るかもしれません。

docs.unity3d.com

なお、以前のResources.UnloadUnusedAssetsは同期で処理を行っていたので、コレを行うと少しの間ゲームが停止してしまう問題がありましたが、現在は非同期で動作しており、あまりゲームを止める心配がありません。

但し、非同期で動作するため、連続して呼出すると何らかの問題が起こるかもしれません。

【Unity】iOSでASTCフォーマットのテクスチャ圧縮を使う

今回はPVRTCと比較して割と綺麗で消費メモリも少ないASTCフォーマットのテクスチャ圧縮を使用する方法についてです。

ASTCについて

wlog.flatlib.jp

ブロックの大きさを指定可能で、ブロックのサイズが大きければ大きいほど圧縮率が高く、汚くなります。

PVRTCが1ピクセルを4ビットで表現しているのに対し、ASTC 6x6は3.56ビット、ASTC 12x12は0.89ビットという高圧縮率を誇ります。また、最も圧縮率が低くTrueColor並に綺麗なATSC 4x4でも1ピクセル8bitと、割とコンパクトに収まります。

f:id:tsubaki_t1:20160928235251j:plain

developer.nvidia.com

ASTC を使用する

f:id:tsubaki_t1:20160928234909p:plain

 

ASTCとPVRTCとTrueColorを比較してみる

5.5からだと思いますが、ASTCがiOSでも使用できるようになりました。

実際にiPad proに出力した物を比較してみます。

True ColorとATSC 4x4を比較すると、殆ど見分けはつかないレベルです。これでも消費メモリは半分以下になります。

PVRTCとASTC6x6は大体消費メモリは同じくらいですが、内側に滲んでいるPVRTCと比較してASTC 6x6の方が綺麗に見えます。
ASTC12x12まで行くと非常に汚く見えるようになりますが、消費メモリはガッツリと落ちます。

f:id:tsubaki_t1:20160928235440j:plain

 

使えるのはA8以降のCPU

割と綺麗なASTCですが、使用する為にはA8以上(iPhone6以降)のCPUが必要となります。
ソレ以前のA7のCPUを使用するとTrueColorに解凍し展開するため、汚くロードも長い割にメモリを超喰うという踏んだり蹴ったりな状況になります。

 

実際に解凍できなかった場合、以下のようなメッセージが表示されます。
WARNING: ASTC texture format is not supported, decompressing texture

 

AndroidでのASTC対応端末は、ココが参考になるかもしれません。

OpenGL ES Hardware Database - © 2013-2015 by Sascha Willems

 

関連

tsubakit1.hateblo.j