MMD4Mecanim と Unity 2018.1.0f2 でunexpected token ';'

# 起こったこと

Unity に MMD4Mecanim を用いてMMDモデルを取り込んだところ、普通にSceneの描画やRunはできるが、Buildは通らなくなってしまった。

## エラーメッセージ

```
Shader error in 'MMD4Mecanim/MMDLit-NoShadowCasting-BothFaces': syntax error: unexpected token ';' at Assets/MMD4Mecanim/Shaders/MMD4Mecanim-MMDLit-Surface-ForwardAdd.cginc(49) (on metal)
Shader error in 'MMD4Mecanim/MMDLit-NoShadowCasting-BothFaces': syntax error: unexpected token ';' at Assets/MMD4Mecanim/Shaders/MMD4Mecanim-MMDLit-Surface-ForwardAdd.cginc(49) (on glcore)
Shader error in 'MMD4Mecanim/MMDLit-Transparent': syntax error: unexpected token ';' at Assets/MMD4Mecanim/Shaders/MMD4Mecanim-MMDLit-Surface-ForwardAdd.cginc(49) (on metal)
Shader error in 'MMD4Mecanim/MMDLit-Transparent': syntax error: unexpected token ';' at Assets/MMD4Mecanim/Shaders/MMD4Mecanim-MMDLit-Surface-ForwardAdd.cginc(49) (on glcore)
Error building Player: 4 errors
```

## 環境

Mac OSX High Sierra バージョン 10.13.4
MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)
Unity Version 2018.1.0f2 Personal
MMD4Mecanim 2018/03/04 版 (β)


# 解決方法

以下の4ファイルを変更する。

```diff:MMD4Mecanim-MMDLit-Surface-ForwardAdd.cginc
...
inline half3 frag_core(in v2f_surf IN, half4 albedo)
{
--	float atten = LIGHT_ATTENUATION(IN); // SHADOW_ATTENUATION() might be 1.0 (Can use LIGHT_ATTENUATION() only.)
++	UNITY_LIGHT_ATTENUATION(atten, IN, IN.pack0.xyz); // SHADOW_ATTENUATION() might be 1.0 (Can use LIGHT_ATTENUATION() only.)
	#ifndef USING_DIRECTIONAL_LIGHT
	half3 lightDir = normalize((half3)IN.lightDir);
...
```

```diff:MMD4Mecanim-MMDLit-Surface-ForwardBase.cginc
...
struct v2f_surf {
	float4 pos : SV_POSITION;
--	float2 pack0 : TEXCOORD0;
++	float4 pack0 : TEXCOORD0;
	half3 normal : TEXCOORD1;
	half3 vlight : TEXCOORD2;
...
inline half4 frag_core(in v2f_surf IN, half4 albedo)
{
--	float atten = LIGHT_ATTENUATION(IN);
++	UNITY_LIGHT_ATTENUATION(atten, IN, IN.pack0.xyz);
	half shadowAtten = SHADOW_ATTENUATION(IN);
	half3 c;
...
```

```diff:MMD4Mecanim-MMDLit-SurfaceEdge-ForwardAdd.cginc
...
struct v2f_surf {
	float4 pos : SV_POSITION;
++	float4 pack0 : TEXCOORD0;
	LIGHTING_COORDS(0,1)
};
...
	MMDLIT_CLIP(alpha)

--	half3 c = MMDLit_Lighting(albedo, LIGHT_ATTENUATION(IN), half3(0.0, 0.0, 0.0));
++	UNITY_LIGHT_ATTENUATION(atten, IN, IN.pack0.xyz);
++	half3 c = MMDLit_Lighting(albedo, atten, half3(0.0, 0.0, 0.0));
	c = min(c, 1.0);
	c *= alpha;
...
```

```diff:MMD4Mecanim-MMDLit-SurfaceEdge-ForwardBase.cginc
...
struct v2f_surf {
	float4 pos : SV_POSITION;
++	float4 pack0 : TEXCOORD0;
	LIGHTING_COORDS(0,1)
	half3 vlight : TEXCOORD2;
...

	MMDLIT_CLIP(alpha)
	
--	float atten = LIGHT_ATTENUATION(IN);
++	UNITY_LIGHT_ATTENUATION(atten, IN, IN.pack0.xyz);
	half3 c;

...
```

これでビルドが通るようになった。

# 原因究明までの道のり

エラーメッセージでググるも、一切ヒットせず。

エラーメッセージから、`LIGHT_ATTENUATION()`マクロが文末にセミコロンを持ってしまっているのではないかという予測を立て、`MMD4Mecanim`プロジェクト内で`LIGHT_ATTENUATION`を検索した。
`ifdef`側でヒットしたのが以下。

```:MMD4Mecanim-MMDLit-AutoLight.cginc
...
#undef LIGHT_ATTENUATION

#ifdef POINT
#define LIGHT_ATTENUATION(a)	(tex2D(_LightTexture0, dot(a._LightCoord,a._LightCoord).rr).UNITY_ATTEN_CHANNEL)
#endif

#ifdef SPOT
#define LIGHT_ATTENUATION(a)	( (a._LightCoord.z > 0) * UnitySpotCookie(a._LightCoord) * UnitySpotAttenuate(a._LightCoord.xyz) )
#endif


#ifdef DIRECTIONAL
	#define LIGHT_ATTENUATION(a)	1.0
#endif


#ifdef POINT_COOKIE
#define LIGHT_ATTENUATION(a)	(tex2D(_LightTextureB0, dot(a._LightCoord,a._LightCoord).rr).UNITY_ATTEN_CHANNEL * texCUBE(_LightTexture0, a._LightCoord).w)
#endif

#ifdef DIRECTIONAL_COOKIE
#define LIGHT_ATTENUATION(a)	(tex2D(_LightTexture0, a._LightCoord).w)
#endif
```

このファイルをいろいろ弄ったりしていたのだが、結局このファイルが読み込まれていない部分でもエラーが出ていたので、その時間は全部無駄になった。


検索してもあまりにも何もヒットしないので、Unityの最新版でのみ起こるバグではないかと考え、検索キーワードに`Unity5`を追加、検索ツールで1年以内を指定。これが効いて、以下のサイトがヒットした。

https://forum.unity.com/threads/missing-changed-light_attenuation-macro.511767/

マクロがdeprecatedになっていたのが原因だったことが判明。

`UNITY_LIGHT_ATTENUATION`マクロの第3引数がよくわからなかったので、実用例を探す。（ドキュメントなどというものはどうやらないらしい。闇。）

https://github.com/Invertex/ShaderForge/blob/9120322ccc917ce5a96e38f05ca22cce27f3d81b/Shader%20Forge/Assets/ShaderForge/Editor/InternalResources/Shader%20Presets/PresetBasic.shader

このdiffがわかりやすかった。
どうやら、第3引数にはセマンティクスが`TEXCOORD0`になっている変数を指定するらしい。

シェーダーセマンティクスについてはこれがわかりやすかった。
https://qiita.com/sune2/items/fa5d50d9ea9bd48761b2

また、型が`float2`に指定されているものを、`float4`に勝手に変更してもいいのか、なども調べた。（結論としては大丈夫っぽい。）

以上を踏まえて`LIGHT_ATTENUATION`マクロを撲滅したのが先述したdiffになる。


# 感想

独自言語とマクロとドキュメントのないAPIは全員まとめていますぐ爆発四散してほしい。