■プリプロセッサ定義の使い方 (Unity 4以降)
Unity 4.0よりプリプロセッサ定義がUnity本体によってサポートされるようになりました!ビルドスクリプトからも自由にアクセスが可能になっており、非常に簡単に扱うことが可能です。
詳しくはけいごさんのブログに完璧にまとめられていますのでそちらをご覧ください。
http://anchan828.tumblr.com/post/32669868103/define
■プリプロセッサ定義の使い方 (Unity 3.5以降)
ここからが本題になります。Unity 3.5以前はプリプロセッサ定義を公式にサポートしていません。そこで以下の4種類のファイルをAssetsフォルダ直下に置くことでプリプロセッサ定義を読み込ませます。
このrspファイルにはC#コンパイラのコンパイラオプションとして渡すオプションが記述できます。ですので http://linux.die.net/man/1/mcs などに列挙されているコンパイラオプションであればひと通りなんでも使用可能です。今回はプリプロセッサ定義をやりたいので、以下のように書けばOKです。/Assets/smcs.rsp (C#用) /Assets/gmcs.rsp (C#エディタスクリプト用) /Assets/us.rsp (UnityScript、俗にJSと呼ばれている物用) /Assets/boo.rsp (Boo用)
-define:DEBUG複数の定義が書きたい場合は、
-define:DEBUG -define:USE_DEV_SERVERのようにスペースで空けて複数記載するか、
-define:DEBUG -define:USE_DEV_SERVERのように改行して複数記載するか、
-define:DEBUG;USE_DEV_SERVERのようにセミコロンで列挙して書くことができます。注意点として、C/C++/Objective-Cのdefineマクロと違って
-define:DEBUG=1のように値を定義することはできないみたいです。あくまでシンボルを作るだけみたいですね。
以下Twitterでのやりとりです。
@akisutesama -define:HOGE -define:FUGA みたいに書けば複数定義出来ますよ。行を分けてもOK。ただしレスポンスファイル(rsp)を修正したらスクリプトは再コンパイルされる必要があるのでスクリプトをすべて再インポートしてください
— Hiroki Omae (@pigeon6) November 9, 2012
@akisutesama 念のために書いておくと.rspファイルはヘンな黒魔法ではなく応答ファイル(response file)といって、要するにコンパイラに渡すコマンドラインオプションをファイルに書いておけるという方式です。なので中身はただのC#コンパイラオプションでございます
— Hiroki Omae (@pigeon6) November 9, 2012
はい、mcsのmanページでよいと思います。オプションに関する情報ではないですがこちらも未読なら読んでおくと良いと思います mono-project.com/CSharp_CompilerRT @akisutesama: @pigeon6 ですよね、コンパイラオプションですよね?ってことは…
— Hiroki Omae (@pigeon6) November 9, 2012
@akisutesama 応答ファイルの利用はUnity的には公式機能ではないので、あまりやりすぎないようにした方がよいです。Unityはビルド時にコードの最適化を行ったり、特にiOSではAOTをやったりと結構事後処理を頑張っているので、そこでおかしくなる可能性はあります。
— Hiroki Omae (@pigeon6) November 9, 2012
さて、これでプリプロセッサ定義はバッチリできるようになったのですが、問題はこれをビルドごとに書き換える方法です。最初はビルドスクリプトでこのrspファイルを書き換えていたのですが、どうもこれをUnityが全く認識しないのです。普通にファイルをただ書き換えてもダメなようです。
そこで黒魔術を導入します。以下のスクリプトで使われているコードを利用して、無理やり書き換えた後のrspファイルをUnityに認識させます。
https://github.com/prime31/P31UnityAddOns/blob/master/Editor/GlobalDefinesWizard.cs#L131
AssetDatabase.Refresh(); reimportSomethingToForceRecompile(); private void reimportSomethingToForceRecompile() { var dataPathDir = new DirectoryInfo( Application.dataPath ); var dataPathUri = new System.Uri( Application.dataPath ); foreach( var file in dataPathDir.GetFiles( "GlobalDefinesWizard.cs", SearchOption.AllDirectories ) ) { var relativeUri = dataPathUri.MakeRelativeUri( new System.Uri( file.FullName ) ); var relativePath = System.Uri.UnescapeDataString( relativeUri.ToString() ); AssetDatabase.ImportAsset( relativePath, ImportAssetOptions.ForceUpdate ); } }これでC#で書かれたコードに対しては無事にrspファイルへの変更が反映されるようになります。
しかしながら更に落とし穴があります。UnityScript(JavaScript)で書かれたファイルに対してはこの黒魔術が効きません。したがってUnityScriptで書かれたファイルに対して動的にus.rspファイルの定義を適用することができないようです。すべてのJSファイルに対して上記の黒魔術を適用しても効果がなかったため、おそらくダメだと思われます。
■結論
UnityScriptは使わないようにしましょう。