Unity5에 또 작은 기능이 추가되었다. 바로 RuntimeInitializeOnLoadMethod 이라는 attribute 이다.


이것은 unity game이 실행 될때, 무조건 실행되는 함수이다.

Editor에서 InitializeOnLoadMethod와 동일한 기능을 하는 기능이다.

다른 점은 RuntimeInitializeOnLoadMethod은 게임 실행시에 처음 실행되는 기능이라는 것이다.


Unity4에서도 계속 이런 기능을 원했건만, 드디어 추가 되었다.

static constructor는 누군가가 이 class를 접근해야만 실행되는 거라서, 실행이 불확실했는데, 이제는 단순히 이 attribute를 사용만 하면 된다.

주의할 점은 RuntimeInitializeOnLoadMethod가 항상 제대로 실행되지는 않는다. Editor에서는 잘 실행되면 메서드가, 모바일 빌드해서 돌리면, 실행되지 않는 경우가 발생한다.

현재까지 경험한 바로는 DLL로 미리 빌드해 넣은 Plugin에 있는 RuntimeInitializeOnLoadMethod는 Editor에서는 실행되고, mobile 빌드에서는 실행되지 않는다.

Posted by 바람인생
,

Unity4에서 부터 계속 editor상에서 무슨 변화가 있으면, noti되는 기능을 찾았지만, 찾지 못했다.

Unity5에서 이게 드디어 지원된다.

아래 delegation 이다.


Undo.postprocessModifications


단 Undo에 등록되는 변화에만 처리되는 것으로 보인다.

참고로 Unity5에서는 매 frame마다 SceneView가 Render된다.

Unity4에서는 변화가 있을 때만 SceneView가 Render되었는데, 이상한 변화이다.

이로 인해서 앞서 말한 기능을 찾아서 사용하게 되었다.

Posted by 바람인생
,

Shader가 Asset Bundle에 포함되면, 이 Shader는 제대로 표현될까?

Shader는 평상시에 text 형태의 소스코드로 존재해서, windows editor에서는 d3d로 동작하고, 모바일 기기에서는 open gl es나 metal 로 동작된다.

즉 소스코드로 존재할 때는 unity가 알아서 현재 동작되는 플랫폼에 맞는 binary로 빌드해서 처리해 준다.


문제는 shader 를 AssetBundle안에 묶을 때 발생한다.

Shader가 Asset Bundle에 포함되면, 소스코드 형태로 들어가지 않고, 타겟 플랫폼으로 빌드된 형태로 포함되게 된다.

따라서 이 Asset Bundle을 타겟 플랫폼에서 사용하면 잘 동작하지만, 다른 플랫폼에서 사용하면 Shader.isSupported가 false로 나오면서 핑크 또는 검정색으로 뜨게 된다.


이게 당연한 얘기처럼 들릴 수도 있겠지만, Asset Bundle을 개발을 위해서 editor에서 돌릴 때 문제가 된다.

editor에서 android 타겟으로 빌드한 asset bundle을 열어서 사용하게 되면, 타겟 플랫폼은 android이고, 현재 플랫폼은 windows이므로 shader가 지원되지 않는다.

즉 분홍색 또는 검정색으로 나오게 된다.


이런 현상을 처음 겪게 되면, 유니티 버그로 인식하게 되고...... 절망하게 된다.

이를 피할 수 있는 방법은 editor에서만 shader를 Shader.Find()로 한 번 더 찾아서, 연결시켜주면 된다.

오직 editor에서만 이런 처리를 해주면 된다. 타겟 플랫폼에서는 원래 잘 되기 때문이다.


좀 더 편리한 해결 방법이 있을까?

http://www.mingruijiang.com/Shaders-from-asset-bundles-appear-pink-in-editor

Posted by 바람인생
,

StreamingAssets 폴더는 Platform마다 다르다.

게다가 더 기가막힌게, Application.streamingAssetsPath를 그대로 믿고 사용할 수 없다는 것이다.

게다가 Unity 문서는 지나간 내용을 설명하고 있으며, 잘못된 내용을 설명하고 있다.

http://docs.unity3d.com/kr/current/Manual/StreamingAssets.html

이런~~~~


정답은 아래와 같다.

#if UNITY_EDITOR || UNITY_STANDALONE_WIN

public static readonly string StreamingPath = "file://" + Application.streamingAssetsPath + "/";

#elif UNITY_ANDROID

public static readonly string StreamingPath = Application.streamingAssetsPath + "/";

#elif UNITY_IOS

public static readonly string StreamingPath = "file://" + Application.streamingAssetsPath + "/";

#endif


Posted by 바람인생
,

Unity4.6에서 Light의 속성을 Baked Only로 해도, 실시간 적용되는 문제가 있다.

모든 경우에 발생되는 것인지, 특수한 경우에만 발생하는 것인지 파악은 안 되었다.

아무튼 Baked Only 라이트는 라이트맵 구운 다음에는 아예 disable 하는 것이 좋겠다.

Posted by 바람인생
,

또 플랫폼마다 다르게 동작하는 문제가 있다.

바로 shader에서 float 타입 변수를 선언할 때마다 결정하는 것이 정확도이다.

지금까지는 이걸 굳이 신경 안써도 잘 동작해서, 왜 이런게 존재하나 했었는데. 최근에 이 차이로 인한 문제를 경험했다.


Specular와 Overlight를 지원하는 shader를 구현하여 모바일 빌드를 했는데, Android와 iOS의 화면이 다르다.

Android에서는 정상적으로 출력되는데 iOS에서는 하얗게 타서 나오는 것이다.

원인을 찾아보니, spec과 glow를 처리하는 코드에서 fixed 타입 변수를 사용했는데, 이 타입 변수는 정확도 뿐만 아니라 표현할 수 있는 범위도 매우 제한적이어서, 정확한 계산이 안 되는 것이다.

그런데 이 문제는 iOS에서만 발생한다. 즉 각 플랫폼마다 또 동작이 다르다.. (이구~~~)


문서를 보면, fixed는 -2 ~ + 2까지만 표현되고, half는 2**-15 ~ 2**+15 까지 표현된다고 한다.

보통 spec과 glow는 큰 값이 들어오므로, 이들의 외부 parameter 선언을 half로 선언하니 문제가 해결되었다.

Posted by 바람인생
,

Varying Semantic 중 Color가 iOS와 PC, Android가 다르게 동작한다.

모자란 TEXCOORD# 대신에 COLOR0과 COLOR1을 사용하여 조금이라도 절약을 하는데...


COLOR는 원래 fixed function 시절 부터 LDR color를 전달하기 위한 용도로 사용되었다.

따라서 이 COLOR semantic으로 전달되는 varying 값은 0~1 의 범위값을 가지며, clamp 된다.


하지만 디바이스 사양이 좋아지면서, iOS에서는 이 제한을 굳이 안 지키고, 범위를 초과하는 값다 잘 전달해 준다.


하지만 PC와 Android기기는 여전히 이 제한을 가지고 있다.


따라서 이 것을 사용하는 shader 코딩을 하고, 범위를 초과하는 값을 전달하는 경우에는 각 platform마다 다른 결과가 나온다.

Posted by 바람인생
,

surface shader가 아니라, 일반 vertex / fragment shader를 작성하게 되면, 많은 부분을 신경써야 한다.

그중에 최근 경험한 것이 shadow map 적용가능하게 하려면, shader에 한가지 코드를 추가해야 한다.

Fallback "VertexLit" 라는 문장이다.

Fallback은 shader 코드의 맨 마지막 block 에 추가한다.

이 문장이 없으면, Shader Inspector에 Cast Shadows가 "No"로 나온다. 이름은 Cast이지만, 이 값이 "No"로 나오면, Receive Shadows도 동작하지 않게 된다.



이상한 Unity3D shader의 세계~~~

Posted by 바람인생
,