Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8901

UnityのManaged code strippingをどうにかする

$
0
0

Managed code stripping is 何?

 ビルドする時、Unityが不要なコードを削除してくれる機能です。ビルドのサイズは小さくなり、時間も短くなるっぽいのでそれなりに良いやつではあります。

リフレクションの罠

 不要判定するには、実際のコードで使用されているかどうかを追ってくれているようなのですが、リフレクションを使って呼び出すようなケースは検知してくれません。リフレクションを使うZenjectのようなDIコンテナを使ってるとわちゃわちゃするわけです。デジゲー博寸前にこいつに気付いて半ベソかきました。

PlayerSettingsで無効化できんの?

 Monoでビルドするときはできます。が、IL2CPPビルドではStripping Levelを調整することはできても無効化することはできません(2019.2.0f1 Personal)。後述の対応が必要です。
スクリーンショット 2019-11-18 16.22.44.png

具体的にStrippingされるもの

 ちょっと追い切れていないのですが、Lowレベルだと、Assetsフォルダ内にあるものはStrippingされないようです。一方、自作package等をインポートして、Packageフォルダ内にあるものをリフレクションでしか呼び出さないような場合はStippingされます。自分はこいつをZenjectで呼び出してやられました。

対応

 以下のような感じのlink.xmlを書いて、Assetsフォルダ以下に置きます。これでビルドしてもStrippingされなくなります。

<linker><assemblyfullname="***"preserve="all"/></linker>

具体例

Packageフォルダ内にあるもの

 PackageManagerでインポートしました。
 同じフォルダ内には他にインポート用のpackage.jsonやSayHello.asmdefファイルがあります。

ITarget.cs
namespaceSayHello{publicinterfaceITarget{stringTarget();}}
Greeter.cs
namespaceSayHello{publicclassGreeter{privatereadonlyITarget_target;publicGreeter(ITargettarget){_target=target;}publicstringGet()=>$"ハロー, {_target.Target()}";}}

Assetsフォルダ以下

Mac.cs
usingSayHello;publicclassMac:ITarget{publicstringTarget()=>"マック";}
Installer.cs
usingSayHello;usingZenject;publicclassInstaller:MonoInstaller{publicoverridevoidInstallBindings(){Container.Bind<ITarget>().To<Mac>().AsSingle();Container.Bind<Greeter>().AsSingle();}}

次のGreeting.csは適当なuGUIのTextにアタッチします。

Greeting.cs
usingSayHello;usingUnityEngine;usingUnityEngine.UI;usingZenject;publicclassGreeting:MonoBehaviour{[Inject]privateGreeter_greeter;voidStart(){GetComponent<Text>().text=_greeter.Get();}}

link.xmlがない状態での動作

スクリーンショット 2019-11-18 15.53.30.png
 Editor上でTextに入れていた文字がそのまま表示されてしまいました。左下に
MissingMethodException: Constructor on type 'SayHello.Greeter' not found.
NullReferenceException: Object reference not set to an instance of an object.
とか出てますね。下ネタなんかを入れていたら、元祖西遊記スーパーモンキー大冒険の再来です。

link.xmlを書く

次のlink.xmlを書いてAssetsフォルダに置きます。

link.xml
<linker><assemblyfullname="SayHello"preserve="all"/></linker>

スクリーンショット 2019-11-18 16.10.49.png

無事に動いてくれました。

参考

Unity Manual : Managed bytecode stripping with IL2CPP


Viewing all articles
Browse latest Browse all 8901

Trending Articles