336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

안드로이드 개발 환경 설정


-------- 주의 ---------

이 글의 내용은 더 이상 필요가 없는 설정입니다. 이제는 유니티 허브에서 모듈 추가 시 체크만 해주면 안드로이드 빌드 설정은 유니티가 알아서 해줍니다. 아래 3개의 체크 박스만 확인해주심 땡입니다요




유니티의 프로젝트를 안드로이드로 빌드하기 위해서는 우선 빌드 타겟을 안드로이드로 설정해줘야 합니다.


File > Build Settings 로 빌드셋팅창을 열고 Platform을 Android 로 선택 후 Switch Platform 버튼을 눌러서 빌드타겟을 안드로이드로 바꿉니다.


만일, 안드로이드 빌드용 모듈이 설치되어 있지 않다면 다음과 같이 No Android Module loaded 라는 메시지가 나옵니다. 메시지 바로 아래 있는 Open Download Page 버튼을 눌러 모듈을 다운로드받고 설치해줍니다. 모듈 설치시에는 유니티를 종료시켜줘야합니다. 설치 완료되고나면 유니티를 다시 켜고 프로젝트를 열어줍니다.


Switch Platform 버튼을 누르면 Asset Progress 프로그레스 팝업이 뜬 후 에셋들을 안드로이드 타겟으로 임포트 진행을 처리합니다.

완료되고나면 유니티 상단 타이틀바에 다음과같이 타겟이 안드로이드로 되어있음을 확인할 수 있습니다. ProfilerSampl1은 프로젝트명입니다. 각자 본인이 설정한 프로젝트명으로 표기됩니다.

빌드셋팅창에서 Player Settings 버튼을 누르면 Inspector창에 Player Settings가 뜹니다. Package Name을 변경해줍니다. Package Name은 Rendering 섹션의 하단에 있는 Identification 섹션에 있습니다. Package Name은 안드로이드 패키지의 이름이므로 원하는 이름으로 지으면 됩니다. 다만, com.제작자.프로젝트명 과 같은 형식으로 짓는 것이 일반적입니다.

이제 빌드를 하면 되는데, 유니티로 안드로이드 빌드를 해본 적이 없다면 빌드 전 안드로이드 개발 환경을 셋팅해줘야합니다. 우선, Preferences창을 엽니다. 윈도우즈는 File > Preferences, 맥은 Unity > Preferences. 윈도우 하단의 SDK와 JDK가 비어있는데, 여기에 경로 설정을 해줘야합니다.

우선, SDK는 Android SDK를 의미합니다. 안드로이드 개발을 위해서는 Android SDK가 필수적으로 설티되어 있어야합니다. SDK 항목 우측의 Download 버튼을 누르면 웹브라우저가 열리면서 다운로드 받을 수 있는 Android Studio 페이지로 이동합니다.

다운로드 버튼을 눌러 다운로드받고 설치를 합니다. 설치를 하고나서 Android Studio를 수행하면 다음과 같은 윈도우가 뜹니다. 여기서 Start a new Android Studio Project를 눌러서 새로운 프로젝트를 생성할 필요는 없습니다. 우리가 필요한 것은 단지 SDK가 설치된 위치만 알면 됩니다. 나머지는 유니티가 빌드할 때 알아서 해줍니다.

안드로이드 스튜디오의 새로운 프로젝트를 만드는 대신, 하단의 Configure 버튼을 눌러서 뜨는 리스트 중 SDK Manager 를 선택합니다.

그럼 SDK 매니저가 뜹니다. 이 중 상단의 Android SDK Location의 경로를 복사합니다.

다시 유니티의 Preferences 윈도우로 돌아가서 SDK 항목에 패스를 그대로 붙여넣으면 됩니다.


윈도우즈에서는 Android SDK 경로에 공백이 들어가 있으면 문제가 발생할 수 있습니다. 예를 들어서 사용자 이름에 공백이 들어가게 되면 전체 경로에 공백이 포함되어버리므로 문제가 발생할 여지가 있습니다. Android SDK Location 옆의 Edit 버튼을 눌러보면 다음과 같이 경고가 뜹니다.

이러한 경우에는 다른 경로에 공백이 없이 새로운 폴더를 만들어서 지정해주면 됩니다.


Android SDK를 완료했으면 이제 JDK를 설치해줘야합니다. JDK는 자바 SDK를 의미합니다. 안드로이는 JAVA를 기반으로 개발하게 되어있으므로 JDK가 설치되어 있어야합니다. 역시 JDK 옆의 Download 버튼을 누르면 웹페이지가 열리고 JDK를 다운로드 받을 수 있는 페이지로 이동합니다.

Download JDK 버튼을 눌르면 다음과 같은 선택 페이지로 들어갑니다.

Accept License Agreement를 체크하고, 본인의  PC에 맞는 OS용 설치 파일을 다운로드하여 설치합니다.


이제 유니티 Preferences 윈도우에서 JDK 경로를 입력해줘야합니다. 기본적으로 다음과 같은 폴더에 설치가 됩니다.

윈도우즈 : C:\Program Files\Java\jdk+버젼명

맥 : /Library/Java/JavaVirtualMachines/jdk+버젼명+.jdk/Contents/Home

탐색기나 파인더로 해당 폴더를 확인하신 다음에 JDK 항목에 패스를 기입해주면 됩니다.


SDK와 JDK 설정을 완료했으면 이제 빌드가 가능합니다. 하지만, 안드로이드도 IL2PP 백엔드로 빌드를 하려면  NDK도 추가로 설정을 해주어야 합니다. NDK는 Android Native Development Kit를 의미합니다. C와 C++ 같은 네이티브 코드 언어를 사용하여 앱의 일부를 구현하는 도구 모음입니다. IL2CPP 백엔드를 이용하면 최종적으로 유저 코드를 C++로 변경하기때문에 NDK가 필요합니다. NDK의 경우에는 Android Studio에서 설치가 가능합니다. 하지만 유니티에서는 특정 버전의 NDK를 요구하므로 Android Studio를 통해서 설치하면 버전이 맞지 않을 수도 있습니다. 따라서 SDK와 JDK와 마찬가지로 우측의 Download를 눌러서 다운로드 받습니다. NDK의 경우에는 인스톨 프로그램이 아니라 폴더 압축파일입니다. 윈도우즈의 경우에는 exe로 되어있어서 실행하면 바로 압축이 풀립니다. 맥에서는 bin파일로 되어있어서 터미널에서 커맨드라인으로 압축을 풀어줘야합니다. 우선 터미널을 열고 다운로드 받은 폴더로 이동합니다. 그 후 다음과같이 실행 권한을 추가해주고 압축을 풀어줍니다.

스크린샷 2017-05-19 오전 2.00.13.png

압축 푼 폴더를 적당한 위치로 옮겨주고 해당 경로를 Preference에 입력해줍니다.

스크린샷 2017-05-19 오전 2.11.02.png


Android SDK, JDK, NDK 모두 설치가 되었으면 이제 디바이스에 띄워볼 차례입니다. 우선, 안드로이드폰과 작업 PC를 USB로 연결해줍니다. Build Settings 윈도우로 돌아가서 Build And Run 버튼을 누르면, 빌드할 apk파일명을 물어봅니다. 원하는 이름으로 입력해주면 빌드가 진행됩니다.


만일, SDK 패스등이 제대로 설정되어 있지 않다면 빌드 시 다음과같은 실패 메시지가 뜹니다.

SDK 패스 설정이 잘 되어있음에도 불구하고 위와 같은 실패 메시지가 뜬다면, 유니티를 껏다 켜보고 OS 재부팅도 해보세요 :)


만일, 안드로이드 디바이스가 디버깅 환경 설정이 되어있지 않다면 다음과 같은 팝업창이 뜹니다.

안드로이드 디바이스는 기기를 개발용 디버깅이 가능한 개발자 모드로 설정을 해줘야 프로젝트를 빌드하여 띄울 수 있습니다. 개발자 모드 설정은 안드로이드OS 버전이나 기기마다 방법이 조금씩 상이합니다. 구글에서 본인의 테스트 기기에 대한 개발자 모드 방법을 검색하면 쉽게 방법을 찾을 수 있습니다.

개발자 옵션을 활성화시키고나면 개발자 옵션에 들어가서 USB 디버깅을 활성화시켜주면 됩니다.

또한, Windows OS의 경우에는 디바이스의 드라이버를 설치해줘야 합니다. 디바이스 벤더 사이트에서 해당 디바이스에대한 드라이버를 다운로드 받을 수 있습니다.

이제 다시 Build Settings 창에서 Build And Run 버튼을 누르면 빌드가 진행되고 빌드가 완료되면 디바이스에 apk가 자동으로 설치되고 게임이 수행됩니다. 디바이스에 맨 처음 연결하는 것이라면 디바이스에서 디버깅 연결할 지 여부를 묻는 창이 뜰 수도 있습니다. 이러한 경우에는 승인 전 까지는 PC에서 디바이스 연결이 실패하기때문에 승인 후 다시 빌드해줘야 할 수도 있습니다.


만일 타겟팅하고 있는 Android API Level(Edit>Project Settings>Player>Other Settings>Identification)이 설치가 되어있지 않은 경우에는 빌드시 Target SDK가 설치되어 있지 않다는 메시지가 뜰 수도 있습니다.


이러한 경우에는 Android Studio의 SDK Manager를 열어서 SDK Platforms 탭에서 해당 SDK를 체크해주고 Apply를 누르면 해상 SDK를 설치합니다.



더 많은 내용은 "유니티 그래픽스 최적화 스타트업"을 참고하세요


Posted by ozlael
,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

문서들을 여기 저기 따로 공유하려느 번거로워서 유니티 최적화 관련 문서들을 모아두었습니다. 정리는 두서 없이 했고,다만 출처가 유니티 크루인지 아닌지로만 분류하였습니다. 추가적으로 발견하는 대로 지속적으로 갱신 할 예정입니다.

Update : 2018-07-10


From Unity


from Developers




Posted by ozlael
,

Unity OVR Input

Unity3D/Others 2017. 9. 30. 15:34
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

VR컨텐츠를 만들 때 일반적으로는 양대 HMD( 오큘러스, 바이브)를 모두 지원해야합니다. HMD 디바이스만 지원하는 것은 매우 쉽습니다. HDM의 트래킹을 지원하기 위해서 별도의 SDK나 에셋을 필요호 하지 않고 유니티의 기본 기능으로 충분하기 때문입니다. 하지만 문제는 컨트롤러의 트래킹과 입력을 지원하는 경우에 발생합니다. 오큘러스와 바이브 컨트롤러를 지원하기위해서는 각각의 SDK를 임포트해서 사용해야합니다. 예를 들어서, 오큘러스 터치를 지원하기 위해서는 오큘러스 디벨로퍼 센터에서 오큘러스 유틸리티를 받아서 임포트해야 합니다. 또한, 바이브 컨트롤러를 지원하기 위해서는 스팀VR  플러그인은 에셋스토어로부터 받아서 임포트해야합니다. 결과적으로는 컨트롤러 관련하여 각각 다른 코드와 프리팹들을 관히애하 합니다. 이는 프로젝트를 개발하고 유지보수하는데 있어서 매우 번거로운 상황입니다. 하지만, 만일 컨트롤러 시스템이 간단한 컨텐츠를 만든다면, 더 이상 이럴 필요가 없습니다. 유니티는 VR 트래킹 API를 제공하고있고, 이를 이용해서 컨트롤러의 위치를 트래킹 할 수 있습니다. 컨트롤러를 트래킹하기 위해서 추가적인 SDK를 유니티 외부로부터 임토프하지 않아도 됩니다. 유니티에서 제공하는 API만으로도 구현이 가능합니다. 버튼 및 트리거 입력은 유니티의 기본적인 인풋 시스템을 이용하면 됩니다.

If you want to make VR content, you have to support all of major HMDs.(Oculus and Vive at this moment :p) You may know supporting HMD devices only is very easy. You don't need any additional SDK or assets to track and support HMD deivces. Problem is supporting and tracking controllers. If you want to support both Oculus Touch and Vive Controller , you may import both SDKs. For Oculus Touch, You have to import Oculus Utilities for Unity rom Oculus Developer Center. And for Vive Controller, you have to import SteamVR Plugin from Unity Store. As a result, you have to use different prefabs and different codes to support both different controller systems. It is very annoying stuff for maintaining. Actually, you don't have to do it anymore, if your controll input system is simple. Unity provide VR tracking APIs to track posion of controllers. To track controllers, you don't have to import additional SDKs from out of Unity. You can do it as using API built inside unity. Plus, You can get input of triggers and buttons from controllers using basing Input system of Unity.


VRControllerTracking.cs :

transform.localPosition = InputTracking.GetLocalPosition (whichNode);

transform.localRotation = InputTracking.GetLocalRotation (whichNode);


컨트롤러 인풋을 얻어오기 위해서는 유니티 공식 매뉴얼을 참고하면 됩니다 : Input table for OVR controllers, Input API, Input Manager. 이는 일반적인 게임 컨트롤러와 동일합니다. 인풋 매핑 테이블을 참고하면 됩니다. 예를 들어서,  LeftHandTrigger를 얻어오고 싶으면, 조이스틱 버튼 14에 해당합니다.

To get input of controllers, You may refer official manual : Input table for OVR controllers, Input API, Input Manager. It is the same with general game controllers. Look at the input mapping table. For example, if you want to get LeftHandTrigger, it will say Joystick Button 14 in there.


LaserSwordControl.cs :

if (blade && Input.GetAxisRaw (inputNameToActiveBlade) > 0.1f) {


자세한 코드와 내용은 샘플 프로젝트 코드를 참고하세요 : https://github.com/ozlael/UnityDemo_InputForOVR

Posted by ozlael
,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


게임을 개발함에 있어서 가장 중요한 것은 물론 재미입니다. 게임은 재미를 주는 것이 주 목적이니 당연한 이야기겠죠. 하지만, 게임을 아무리 재밌게 만들었다 하더라도 게임이 실행이 되야 재미를 느낄 수 있겠죠. 게임을 플레이하다가 게임이 자꾸 강제 종료되버린다면 말짱 도루묵이 되겠죠.

그렇기 때문에 게임 개발에 있어서 메모리 이슈도 중요합니다. 특히 모바일 환경에서는 더 심하죠. PC에서는 실제 물리적인 램이 부족하더라도, 디스크의 공간을 활용하여 모자란 메모리를 보조하는 시스템이 존재합니다. 때문에, 현대의 PC에서는 게임이 버벅일지언정 메모리 부족으로 게임이 강제종료되는 상황까지 가는 것이 흔치는 않습니다. 하지만, 스마트폰에는 그러한 기능이 존재하지 않습니다. 그말인 즉슨, 실제의 물리적인 메모리 공간을 넘어서 사용이 불가능하다는 것을 의미합니다. 그렇기때문에, 스마트폰 게임이 메모리를 많이 사용한다는 것은 게임이 뜻하지 않게 강제종료될 가능성이 그만큼 많아진다는 것을 의미합니다.  

스마트폰 게임을 개발할 때에는 항상 메모리에대해서 신경쓰면서 개발을 해야합니다. 하지만 메모리를 줄여야 하는 것은 알겠는데, 무엇을 어떻게 줄여야 할지 막막한 채로 작업을 할 수는 없겠죠. 그렇기 때문에  메모리도 프로파일링이 필요합니다.


유니티 5.3부터는 메모리 프로파일러라는 확장 툴을 이용하여 메모리를 확인할 수 있습니다. 이 툴을 이용하면 어떤 메모리가 얼만큼의 힙 메모리를 사용하고 있는 지를 직관적으로 쉽게 확인 할 수 있습니다.

다운로드 : https://bitbucket.org/Unity-Technologies/memoryprofiler/downloads/

아쉽게도 아직 유니티 기본 내장 툴은 아니고, 에디터 확장 기능으로 따로 다운로드받아서 사용해야합니다. 유니티도 오픈소스 형태로 개발하는 기능들이 많이 있는데요, 빗버킷에 올려두고 개발을 진행합니다. GUI 시스템도 마찬가지고 Post Processing Stack, Asset Bundle Manager 등등 많은 프로젝트들이 오픈소스 형태로 진행중입니다. 메모리 프로파일러 역시 이 중 하나라고 보시면 됩니다. 

유니티 5.3 이상부터 적용이 가능합니다. 다운로드 받은 프로젝트의 에디터 폴더를 현재 현재 개발중인 프로젝트의 에디터 폴더로 임포트 하면 됩니다. 스크립트 백엔드는 IL2CPP로 적용해줘야합니다. 안드로이드 역시 IL2CPP가 정식 지원되고 있기 때문에 안드로이드도 사용이 가능합니다. 다만 주의할 점은 5.3에서는 안드로이드 IL2CPP가 정식 지원이 아니라는 점입니다. 결론적으로는 메모리 프로파일러를 이용하려면 5.3을 이용중인 프로젝트라면 5.4 이상으로 업데이트를 해야한다는 의미가 됩니다.

메모리 프로파일러는 내부적으로 Profiler API를 이용합니다. 그렇기 때문에, Development Build로 빌드하여야 합니다. 게임을 띄우고나면 유니티 프로파일러를 띄우고 디바이스에 프로파일러를 연결하여 프로파일링이 되는 것을 확인합니다, 그 뒤에 유니티에서 Windows>Memory Profiler를 선택합니다.

그럼 이렇게 생긴 메모리프로파일러 윈도우가 뜹니다. 이 화면에서 Take Snapshot 버튼을 누르면 됩니다. 디바이스에서 데이터 긁어오다보니까 폰이 잠깐 멈췄다가 가져온 데이터를 분석하느라 에디터가 잠깐 멈출겁니다. 데이터가 많으면 좀 시간이 걸릴 수도 있기 때문에 인내심이 좀 필요할수도 있습니다.

데이터 분석이 다 끝나면 메모리 사용량을 종류별로 시각화 보여줍니다. 종류별로 메모리를 얼마만큼 차지하는지를 사각형의 크기로 보여줍니다. 사각형 크기 비율이 실제의 메모리 사용량의 비율을 나타냅니다. 즉, 사각형의 크기가 큰 것 을 우선순위로 줄여나가면 되는 것입니다.

항목을 클릭하면 개별 리소스나 오브젝트들의 메모리 차지 면적을 볼 수 있습니다. 우측에는 선택한 오브젝트의 이름 및 인스턴스 아이디 등등의 자세한 내용을 확인할 수 있습니다. 크기가 작아서 보기 힘든 항목들은 마우스 휠을 굴려서 줌인 줌아웃이 가능합니다. 솔직히 인터페이스가 이쁜 편은 아닙니다. 좀 투박한 느낌은 있지만 시각적으로 확인하고 분석하는 기능은 충분합니다.


실제의 예를 하나 들어보겠습니다. 에셋스토어에서 게임을 하나 받아서 갤럭시S2에서 수행한 모습입니다. 2D게임이라 갤럭시 2S에서도 동작하는데 무리가 없습니다.

근데, 문제가 없어보인 것이지 실제로는 문제가 있는 상황입니다. 프로파일링해보기 전에는 문제가 없다고 단정하면 안됩니다. 실제로 메모리 프로파일러로 확인해보니 텍스쳐 메모리 사용량이 엄청납니다. 어떤 텍스쳐는 16MB나 차지하고 있습니다. 

확인해보니 사이즈가 2048이기는 하지만 ETC2 압축을 설정해놓았으니 16MB는 말이 안되는 것 같아보입니다.

사실, 이건 갤럭시2S가 OpenGL ES 2.0만 지원해서 발생하는 현상입니다. 갤럭시 S2는 오래된 모델이라 OpenGL ES 3.0을 지원하지 못하고 OpenGL ES 2.0만 지원합니다. 문제는 ETC2는 OpenGL ES 3.0부터 지원된다는 것입니다. 즉 OpenGL ES2.0에서는 ETC2를 사용하지 못한다는 것입니다. 그래서 OpenGL ES 2.0에서는 ETC2 텍스쳐를 읽어들일 때 ETC2를 압축을 풀어서 메모리에 올라갑니다. 그래서 2048 * 2048 * 4바이트 = 16MB가 되서 메모리에 올라간 것입니다. 

똑같은 텍스쳐를 OpenGL ES 3.0 지원되는 기기에서 확인해보면  텍스쳐 압축이 잘 되서 4MB로 올라갑니다. 그래서 알파가 있는 텍스쳐를 컴프레스트로 두면 OpenGL ES 2.0까지만 지원하는 갤럭시S2랑 OpenGL ES 3.0을 지원하는 갤럭시 S4에서의 실제 텍스쳐 메모리 사용량이 많이 차이가 날 겁니다. (갤럭시 S3로 비교하지 않은 이유는, 갤럭시 S3 중에서도 세부 기종에따라 지원하는 버전이 다르기 때문입니다)


메모리 프로파일러를 이용하면 이런식으로 어떤 리소스가 얼만큼을 차지하고 있는 지를 쉽게 분석할 수 있습니다. 메모리를 프로파일링하기 위해서는 필수적인 툴일 것입니다.

이 툴에 대하여 건의 사항이나 버그가 있다면 아래 주소로 이슈를 만들어주시면 됩니다. 만약 영어가 불편하면 저한테 말씀해주세요.

링크 : https://bitbucket.org/Unity-Technologies/memoryprofiler/issues?status=new&status=open

 제가 사실 블로그 댓글은 잘 확인하지를 않아서 페이스북이나 트위터로 연락 주세요 :)

페이스북 : ozlael.oz

트위터 : @ozlael

Posted by ozlael
,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

이 글은 유니티 자습서Best Practices 문서 중 Resources Folder를 번역/의역한 것입니다.


Resources 폴더

이 글은 “유니티5의 에셋과 리소스 관리” 시리즈의 3번째 글입니다.


이 챕터는 Resources 시스템에 대하여 다룹니다. 이 시스템은 개발자가 여러 에셋들을 Resources 폴더에 두고 런타임동안 Resources API를 통해서 에셋을 로드/언로드할 수 있도록 해줍니다.


2.1 Resources 시스템을 위한 실용 가이드


사용하지 마세요.


다음과 같은 이유들로 사용하지 않기를 강력하게 권고합니다

  • Resources 폴더를 사용하는 것은 메모리 관리를 더욱 복잡하게 만듭니다.

  • Resources 폴더를 부적절하게 사용하면 어플리케이션 시작 시간과 빌드 시간을 늘리게 됩니다.

  • Resources 폴더들이 많아지면 그 안에 있는 에셋들의 관리가 힘듭니다.

  • Resources 시스템은 사용자 정의 컨텐츠를 특정 플랫폼으로 옮기는 것이 까다로워집니다. 컨텐츠를 업그레이드하는 경우도 마찬가지입니다.

  • 디바이스에 맞는 컨텐츠를을 조정하는데 적합한 주요 기능은 에셋번들입니다.


2.2 Resources 시스템의 적절한 사용

다음과 같은 두 가지의 경우에는 개발 시 Resources 시스템을 사용하기에 적합한 경우입니다.

  1. 빠른 프로토타이핑이나 검증이 필요한 경우에는 Resources를 사용하기에 좋습니다. 간단하고 사용하기 쉽기 때문입니다. 하지만, 프로젝트가 프로덕션 단계에 가게 되면 Resources 폴더 사용을 중단해야 합니다.

  2. Resources 폴더는 다음 모든 경우를 만족하는 상황에서는 유용한 시스템입니다.

    • Resources 폴더에 들어있는 컨텐츠들은 메모리에 민감한 것 들이 아닐 경우

    • 컨텐츠가 어플리케이션의 수행 시간 동안 계속 필요한 경우

    • 컨텐츠가 패치될 일이 거의 없는 경우

    • 컨텐츠가 플랫폼이나 디바이스별로 달라지지 않는 경우

이 중 두 번째 케이스에 해당하는 예시는 전역으로 사용되는 싱클턴 모노비헤이비어나 페이스북 앱 ID등의 서드파티 데이터를 다루는 에셋등이 될 것입니다.


2.3 Resources의 시리얼라이제이션

프로젝트 빌드 시 “Resources” 폴더 내 모든 에셋과 오브젝트들은 하나의 시리얼라이즈된 파일에 정보가 담깁니다. 이 파일은 에셋번들처럼 메타데이터와 인덱싱 정보를 포함합니다. “에셋번들 의 근본”챕터의 “에셋번들이란 무엇인가?” 섹션에서 설명된 바와 같이, 이 인덱싱 정보는 시리얼라이즈된 룩업  트리를 포함합니다. 여기에는 주어진 오브젝트 이름을 파일 GUID와 로컬 ID와 매칭시키는데 쓰이는 정보들을 포함합니다. 오브젝트를 시리얼라이즈된 파일의 몇 바이트째 위치시키느냐등의 정보도 포함합니다.


룩업 데이터 구조가 균형잡힌 탐색 트리라서 구축 시간 비용은 O(N log(N)) 비율로 증가합니다.(대부분의 플랫폼에서는 C++ Standard Template Library의 std::multimap를 사용합니다.) 여기서 N은 트리에 들어가는 오브젝트 갯수를 의미합니다. 이러한 증가치는 인덱스의 로딩 타임에 많은 비용이 들게합니다. 따라서 Resources 폴더 안의 오브젝트들이 많을수록 성능에 좋지 않습니다.   


이 동작은 건너뛸 수 없기때문에 어플리케이션의 초기 시작 시간을 늘리게 되서 인터렉션이 불가능한 스플레시 화면이 떠 있는 시간이 길어지는 요인이 됩니다. 특히 저사양 기기일 수록 Resources 시스템에 많은 오젝트가 포함되있으면 어플리케이션 시작 시간이 매우 길어지게 됩니다. 특히, Resources 폴더의 대부분의 오브젝트들이 첫 씬에서 보여질 필요가 없는 경우에는 효율적이지 못한 상황이 되는 것입니다.




Posted by ozlael
,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

게임을 개발하는 과정에서 콘솔 로그를 출력하는 것은 필수적입니다. 당연히 유니티에서도 로그를 출력하는 함수가 존재하고 Debug.Log()를 많이 사용하시죠.

Manual : https://docs.unity3d.com/ScriptReference/Debug.Log.html 


근데 많이들 오해하시는게, 이 Debug.Log 함수는 Debug클래수 함수니까 Development Build일 때에만 작동하고 릴리즈 빌드때는 자동적으로 제거된 다고 오인하시는 것입니다. 콘솔 출력용으로 남발해서 사용되도 최종 릴리즈에는 영향 미치지 않는다고 오인하시는 경우가 많습니다, 하지만 아쉽게도 그렇지 않습니다. Debug.Log()는 릴리즈 빌드때고 고스란히 작동합니다. 따라서 쓸데 없는 성능을 쉽게 잡아먹는 녀석중 하나가 되버리죠.


예를 들어서 다음과 같이 콘솔 출력용 로그를 수없이 찍는 코드를 만들고

public class TestLog : MonoBehaviour {


public int logCount = 500;

public string testStr;

void Update () {

for( int i=0; i< logCount; i++) {

UnityEngine.Debug.Log("test log : " + testStr + "!" );

}

}

}

빈 프로젝트에서 위 코드만 돌린 프로젝트를빌드하여 홍미 폰에 띄우니 30FPS로 돌아갑니다. 디벨롭먼트 빌드가 아닌데도 불구하구요. 물론 실제로 매 프레임마다 500번의 출력을 하는 경우는 실존하지 않을 것입니다. 테스트를 보여주기 위하여 극악의 상황을 만들어본 것 뿐입니다. 다만, Debug.Log()가 쓸데 없이 작동하는 것을 증명하기에 충분한 코드겠지요. 


이러한 쓸데없는 행위를 막기 위해서 #if 디파인문을 많이들 사용하십니다. 다음과 같이요

#if TRACE_ON

UnityEngine.Debug.Log("test log : " + testStr + "!" );

#endif

이렇게 두고 플레이어 셋팅의 Scripting Define Symbols이나 .rsp 파일에 TRACE_ON을 추가하한 경우에만 수행되고 아닌 경우에서는 Debug.Log()가 수행되지 않고 60FPS가 잘 나옵니다.

Manual : https://docs.unity3d.com/Manual/PlatformDependentCompilation.html

이제 문제가 전혀 없습니다. 없을까요? 

있습니다. 귀찮은게 문제지요.


Debug.Log()를 출력하는 곳이 한두군데도 아니고 매번 작성할 때 마다 #if #endif로 묶으려면 매우 귀찮습니다. 게다가 실수로 잘못 묶으면 짜증이 짜증이 아휴~



대안으로는 Conditional를 사용하시면 편합니다. Debug.log()를 래핑하는 클래스를 만들고 함수에다가 Conditional를 선언하면 됩니다.

using UnityEngine;

using System.Collections;

using System.Diagnostics;


public class TestLog : MonoBehaviour {


public int logCount=500;

public string testStr;


[Conditional("TRACE_ON")]

void DebugLogWrap( string str) {

UnityEngine.Debug.Log(str);

}

void Update () {

for( int i=0; i< logCount; i++) {

DebugLogWrap("test log : " + testStr + "!" );

}

}

}

TRACE_ON 디파인이 켜져있지 않는 경우에는 DebugWrap을 호출하는 라인이 통채로 무시됩니다. 따라서 #if 디파인을 매번 사용하지 않고도 같은 효과를 볼 수 있습니다. 사실 저도 얼마 전에 알게 된 것인데 굉장히 편하네요 ㅋ C# 짱짱맨 :)

MSDN : https://msdn.microsoft.com/en-us/library/4xssyw96(v=vs.90).aspx


궁극적으로는 다음 링크처럼 사용하시면 됩니다 : 

https://gist.github.com/kimsama/4123043


끗!


Posted by ozlael
,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

게임은 어떻게 만드나요?

라는 질문에 뭐라고 대답해야 할까요? 누군가는 어떤 말을 해야할 지 고민을 할 테고, 누군가는 쌍욕부터 할 지도 모르겠습니다. 어찌되었건 이런 질문을 받았을 때 공통적으로 느끼는 감정은 '혼란'일 것입니다. 대답해주려니 막막하고 어디서부터 풀어나가야 할 지 혼란스러워진다는 것입니다. 질문을 받은 사람이 이러한 감정을 느끼는 원인은 간단합니다. 바로 질문 자체가 막연하기 때문이죠.

제가 뜬금없이 이런 질문을 언급하는 것이 의아하실지도 모르겠습니다. 이런 질문을 하는 사람이 있을까 싶으시겠지만 실제로 인터넷 커뮤니티(특히 뇌입어)에 많이 올라오는 질문 중 하나입니다. 사실 이러한 비(非)개발 커뮤니티는 이런 허접한 질문이 올라올 수도 있다는 생각이 들 수도 있겠습니다. 하지만, 중요한 것은 개발 관련 포럼이나 커뮤니티에도 이러한 수준의 질문이 가끔 목격된 다는 것입니다. 제가 다소 공격적으로 "수준"이라는 표현을 사용했지만, 여기서 말하는 "수준"이라는 것이 별 뜻은 아닙니다. 질문 내용의 기술적인 난이도가 낮아서 수준이 낮다고 표현하는 것이 아닙니다. 기술적인 수준은 낮아도 질문 자체의 수준이 높은 경우는 얼마든지 많습니다. 제가 말하는 "수준이 낮다"고 표현하는 것은 질문 내용에 성의가 없기 때문입니다. 

예를 들어서 누군가 다음과 같은 질문을 올렸다 생각해보겠습니다.

광선검은 어떻게 만드나요?

이 질문이 뭐가 문제인지 의아해하시는 분도 계실지도 모르겠습니다. 하지만, 제가 보기에는 이 질문이 앞서 언급하였던 게임을 어떻게 만드냐에 대한 질문과 다를 바가 없어보입니다. 마찬가지로 막연하고 정보가 부족하기 때문입니다. 이로 인해서 받아들이는 사람 마다 질문의 의도를 각자 다르게 해석하고 각자 다른 초점의 정보를 말해주게 될 것입니다. 

"광선검"이라는 단어를 들으면 어떤 사람은 스타워즈의 라이트세이버를 떠올릴 것이고 어떤 사람은 건담의 빔샤벨을 떠올릴 것입니다. 

어떤 사람은 모바일 타겟으로 파티클로 빔샤벨을 만드는 방법을 안내할 것이고 어떤 사람은 PC 타겟으로 이미지 블룸 효과를 처리하는 방법을 안내할 것 입니다. 어떤 사람은 그래픽 리소스를 제작하는 방법을 안내할 것이고 어떤 사람은 손잡이에서 빔이 나오는 에니메이션 처리를 수행하는 스크립트를 안내할 것입니다. 이처럼 질문부터가 모호하고 정보가 없으면 질문자와 답변자 모두에게 만족으러운 결과를 도출하지 못하게 될 것입니다. 이는 당연한 결과입니다.

하지만, 의외로 이러한 모호한 질문들이 생각보다 많이 발견됩니다. 물론 예를 들어 말씀드린 질문은 극단적인 예일 뿐이고 사실 더 많은 정보를 포함한 질문들이 대부분입니다. 하지만 여전히 적은 정보만으로 모호한 질문을 물어보는 글들이 많이 보이곤 합니다. 비단 유니티 관련 포럼 뿐 아니라 언리얼, 코코스 등 다른 엔진 관련 포럼에도 나타나는 현상들이고 게임 뿐 아니라 개발 관련 된 커뮤니티라면 어디에서든지 존재하는 현상들입니다.

때문에 질문을 올리는 방법에 대한 가이드를 말씀드리고자 합니다. 물론 이 글이 객관적인 것은 아니며 어떤 기관에서 표준으로 인정한 양식도 아닙니다. 단지 제 개인적인 경험과 노하우를 통해 말씀드리는 것이니 절대적인 가이드라기보다는 참고사항으로만 생각해주시면 감사하겠습니다. 


육하원칙

기본적으로, 육하원칙(5W1H)을 생각하시면 됩니다. 누가,언제,어디서,무엇을,어떻게,왜 육하원칙은 초등학교에서  기본적으로 배우는 만큼 기초적이고 중요한 원칙입니다. 대부분의 질문은 이 육하원칙에서 한가지를 도출하는 과정이 될 것입니다. 어떠한 현상이 왜 생기는지를 물어보고자 한다면 나머지 다섯가지인 누가,언제,어디서,무엇을,어떻게에 대한 정보가 제공이 되어야 할 것입니다. 반대로 어떻게 해야하는지를 물어보고자 한다면 나머지 다섯가지인 누가,언제,어디서,무엇을,왜가 제공이 되어야 할 것입니다. 무조건 이 여섯가지 요소를 반드시 지켜야 한다는 것은 아닙니다. 질문에 따라서 모든 요소가 들어갈 필요는 없는 경우도 있습니다. 다만, 가능한 이 원칙에 입각하여 질문을 작성한다면 크게 모호해질 일은 없을 것입니다. 물론, 이 요소들을 명시적인 도표로 만들어서 작성하거나 하라는 것이 아닙니다. 글의 문맥 안에 이러한 요소들이 명시적이나 암묵적으로 포함되기만 하면 됩니다. 사실, 각각의 요소들에 대한 명확한 기준은 없습니다만 각각의 요소에 주로 담기게 되는 내용을 설명드려볼까 합니다.


누가(who)

"누가"는 대부분 질문자 본인이라 생각 할 수도 있습니다만 당연히 질문자가 이름이 뭔지 거주지가 어딘지따위는 중요하지 않습니다. 중요한 것은 직군이 어디인지 지식 수준이 어느정도 인 지 입니다. 그래야 어느정도 레벨까지 설명을 해 줘야 할 지 가늠할 수 있기 때문입니다. 다만 이러한 것은 질문 내용에서 간접적으로 표현 되는 경우가 많아서 명시적으로 언급해주지 않아도 되는 경우도 많습니다. 예를 들어서 NavMesh.Raycast()의 성능에 대해 물어는 글이 있다 치면, 그 질문의 작성자는 일단 프로그래머이일 것이며 네비게이션 메시에 대한 기본 지식은 가지고 있다고 가정해도 무방할 것입니다. 또한, "누가"는 사람에만 국한 되는 것이 아니라 시스템의 객체가 될 수도 있고 오브젝트의 인스턴스가 될 수도 있는 등 다양한 시각으로 반영될 수 있습니다.


언제(when)

"언제"는 몇시 몇분 몇초의 절대적인 시간이 아니라 재현 시퀀스의 타이밍이 되는 경우가 대부분입니다. "버튼을 세번 눌렀을 때" 혹은 "앱이 수행되자마자 항상" 등 재현 시퀀스상의 시간이 될 수도 있습니다. 때문에, "어떻게"와 같이 묶여서 표현 될 수도 있습니다. 


어떻게(how)

그렇다고해서 "언제"와 "어떻게"가 동일하다는 이야기는 아닙니다. "어떻게"는 주로 구현 방법에 대한 설명이 되는 경우가 많습니다. 어떤 기능을 어떻게 구현했냐에 대한 설명이 대부분일 것입니다. 주로 이 부분에 대한 설명이 자세할 수록 좋습니다.

구현을 어떻게 했고 무엇이 문제인 지에 대한 설명은 사실 말로만 설명하기에는 부족한 경우가 많습니다. 이러한 경우에는 보조적인 자료를 사용해주는 것이 좋습니다. 특히 코드에 관한 것을 물어볼 때에는 반드시 소스 코드가 포함되어야 합니다. 무슨 함수를 어떻게 썼다라는 것을 말로만 설명하는 것이 아니라 해당 코드를 반드시 올려주어야 합니다. 더 나아가서 프로젝트를 올려주시면 정확한 판단을 하기가 훨씬 수월해집니다. 포럼 사이트나 게시판마다 파일 업로드 용량 제한이 달라서 프로젝트 파일을 직접 올리지 못하는 경우가 대부분입니다. 구글 드라이브나 드랍박스에 파일을 올린 후 링크를 걸어두시는 식으로 하면 여러 커뮤니티에 질문을 올릴 때 유용합니다. 물론 프로젝트를 올려두었다 하더라도 문의하고자 하는 부분의 핵심 코드는 본문에 포함되어야 합니다.


어디서(where)

"어디서"는 말 그대로 문제가 발생하는 위치입니다. PC나 모바일 등 물리적인 위치가 될 수도 있고, 어느 클래스 어느 함수에서 발생하는 지 등의 논리적인 위치가 될 수도 있습니다. 위치 역시 최대한 자세히 적어주시는 것이 좋습니다. 예를 들어서 모바일 기기에서만 발생하는 문제라면 단순히 "모바일 기기"라는 표현으로 끝내는 것이 아니라 해당 기기의 모델명과 OS 버젼 등은 필수적으로 기입되어야합니다.


무엇을(what)

"무엇을"은 6가지 요소 중 가장 중요한 요소가 될 수도 있습니다. 구현하고자 하는 것이 무엇인 지 혹은 문제가 발생하는 현상이 무엇인 지 등 원하는 것이 정확히 기술되어야 합니다. 

어느날 사장님이 오셔서 이런 말을 했다고 가정해보겠습니다.

보스를 추가하고싶은데 메카닉이면서도 허접해보였으면 좋겠어. 또한 모던하면서도 클래식한 느낌이 나야해

이 말만 툭 던지고 자리로 돌아간다면 사장이고 뭐고 다 때려엎고 싶을 지도 모릅니다. 설명이란 것은 자세하면 자세할 수록 좋습니다. 여기서만큼은 과유불급이란 것은 존재하지 않습니다. 하지만 사실 아무리 말로 잘 표현하더라도 정확한 표현을 하는데에는 한계가 있을 수 있습니다. 백마디의 말 보다는 한장의 이미지가 더 효과적이라는 것을 항상 염두해두시길 바랍니다. 이까 그 사장님이 다시 돌아와서 다음과 같은 이미지를 던져주고 간다면 그나마 화가 조금은 풀릴 지도 모르겠습니다.

왜(why)

"왜"는 불필요한 정보라고 느낄 수도 있겠지만 이 역시 상당히 중요한 정보입니다. 만일 특정 함수의 오류에 대해 문의하는 것이라면 왜 그 함수의 사용 의도가 파악되어야 합니다. 그래야만 의도하는 방향 내에서 해결책을 제시할 수 있습니다. 또한, 용도에 맞지 않는 사용법으로 사용하는 것을 막을 수도 있습니다. 혹은, 더 나은 방법이 제시 될 수도 있습니다. 예를 들자면, 주기적인 타이밍으로 들어가는 도트데미지를 Update() 함수에서 구현하는 방법에 대한 문의를 한다면 코루틴을 사용하는 것으로 제안 할 수도 있을 것입니다.


아웃라인(outline)

육하원칙 외에도 글의 아웃라인을 서론과 본론으로 갖춰주시는게 좋습니다. 글을 자세히 적다보면 글이 길어질 수 밖에 없는데 서론 없이 바로 본론으로 들어가버린다면 질문에 대한 집중력이 떨어질 수 밖에 없습니다. 그렇다고 너무 아웃라인의 형태에 집착하지 않아도 됩니다. 글의 도입부에서 어떤 주제에 대한 질문인지 대략적으로 밝히고 진입하는 정도만 되어도 충분한 아웃라인을 갖추었다고 봐도 무방합니다.


퇴고

사실, 육하원칙이니 글의 아웃라인이니 그런 것 보다는 퇴고가 가장 중요합니다. 글을 길게 썼든 짧게 썼든 글을 최종 업로드 하기 전에 퇴고를 반드시 거쳐주시길 바랍니다. 제3자의 입장으로 글을 다시 한번 읽어가면서 내용이 이해가 가는지를 판단해보십시요. 의외로 자신이 글을 이해가 가지 않게 썼다는 것을 발견 하는 경우가 많을 것입니다.

이렇게까지 많은 것을 고려하면서 질문글을 써야하나 하는 의문을 제기하는 분도 간혹 계십니다. 물론 질문이란 것이 가볍게 던질 수도 있는 것입니다. 다만 자세한 질문을 할 수록 더 나은 답변과 토론이 오갈 수 있을 것이라 생각합니다. 또한, 질문을 적는 사람은 개인이지만 질문은 많은 사람들이 읽습니다. 더 많은 사람들이 더 많은 시간을 투자해서 함께 고민하는 것이기 때문에 질문 글에도 그만큼의 정성이 들어가는 것이 예의라고 생각합니다.


다시 광선검

마지막으로 다시 광선검을 예로 들어보겠습니다. 

광선검은 어떻게 만드나요?

라는 표현은 다음과 같이 바꿀 수 있겠습니다.(실제의 문의 내용이 아니라 제가 가상으로 작성한 글입니다.)

안녕하세요. 광선검의 검흔 효과 구현에 대한 조언좀 구하고자 문의글을 올립니다. 저희가 모바일 액션 RPG를 만들고 있습니다. D&D나 던파같이 사이드뷰인데 배경이 미래다보니 스타워즈 광선검이 무기로 등장합니다. 광선검 자체를 만드는 것은 문제가 없었습니다만 검흔 효과를 만드는데 애를 먹고있습니다.

검광 부분은 막대기 모델에 따라서 검광 텍스쳐 판때기 2개를 X자로 교차되게 간단하게 만들었습니다. 케릭터에게 쥐어줘보니 뭐 그럴싸합니다. 모바일이라 화면도 작은데다가 광선검이 클로즈업되서 보일 일이 없다보니 판때기로 박은게 티가 잘 안납니다. 근데 단순히 이것만 가지고 검을 휘둘러보니 뭔가 어색합니다. 영화에서 보면 검을 휘두르면 삼각형 모양의 블러가 생깁니다. 게임에서 이런게 안생기니 심심한 느낌입니다.

저는 단순 모델러라 이펙트를 잘 모릅니다. 신생팀이라 이펙터도 따로 없구요. 그래서 옆자리 프로그래머랑 같이 에셋스토어 뒤져서 trail 이펙트를 붙여봤는데 영화에서의 느낌은 나지 않네요. 그냥 일반적인 무협 게임의 검기같은 느낌일 뿐 광선검 특유의 느낌이 나지 않습니다. 검흔 자체가 불투명이어야하는데 빨간 화살표처럼 투명 그라데이션이 들어갑니다. 전체적인 헤일로 효과 없이 노란색 화살표처럼 검 진행 방향의 단면이 선명하게 떨어져버리구요. 영화에서는 순간적으로 검의 모양이 부채꼴로 변하는 듯한 느낌이라 이 이펙트와는 전혀 다른 느낌입니다. 

영화에서의 느낌을 내려면 어떤식으로 구현해야할 지 아니면 어떤 에셋을 사용해야 할 지 조언좀 부탁드립니다. 혹시 몰라서 파일을 올려두었습니다. 프로젝트라 광선검 부분만 따로 패키지로 추출한 점 양해 부탁드립니다.

다운로드 링크 : 어쩌고저쩌고

감사합니다 :)


P.S. 먹튀는 악질 행위입니다. 가끔 답변을 받으면 답변만 확인하고 질문들을 삭제하는 분도 계시는데 이러한 행위는 비매너 행위입니다. 커뮤니티는 다른 사람들과 정보와 노하우를 공유하는 공간입니다. 혼자만 알고싶으면 애초에 커뮤니티에 질문을 올리는 것 부터가 모순이라는 점을 말씀드리고 싶습니다.


로보트 이미지 출처 : Stephane Halleux

게임 trail 효과 이미지 출처 : SWTOR



Posted by ozlael
,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

유니티 배우려는데 무슨 언어로 배워야할까요? C#? 아니면 자바스크립트?

가끔 이러한 질문들을 듣곤 합니다. 일단 이 질문에 대한 대답을 먼저 드리자면 당연 C#입니다. 유니티는 C#과 자바스크립트 두 언어를 지원하기 때문에 유니티 입문 시 이 두 언어 중 무엇으로 사용해야 할 고민이 되곤 합니다. 하지만 고민하실 필요 없이 C#으로 선택하시길 추천드립니다. 

이유는 간단합니다. 많은 사람들이 사용하기 때문이죠. 이는 구글트렌드로 살펴보더라도 극병하게 드러납니다. 물론 구글 트렌드가 객관적이고 정확한 기준 자료가 될 수는 없겠지만, 시간이 지날수록 자바스크립트보다는 C#이 대세로 가고 있음을 확인 하실 수 있습니다.

이미지 : 구글 트렌드

그러다보니 당연히 많은 참고 자료들이 C#으로 되어있습니다. 기능 구현이나 알고리즘 자료들 뿐 아니라 각종 플러그인의 샘플들도 C# 위주로 되어있습니다. 물론 언어의 견고함이라든가 방대한 라이브러리등 더 많은 선택 기준이 있겠지만, 입문하시는 입장에서라면 대세가 C#이라는 이유만으로도 충분하리라 생각합니다.

간혹 SI에서 자바를 다루었거나 웹에서 자바스크립트를 다루었다는 이유로 자바스크립트를 선택하려는 분도 계십니다. 하지만 이는 잘못된 판단입니다. 

여기서 잠깐 질문 하나 하겠습니다. 오리와 오리너구리와 KOF이오리의 공통점은 무엇일까요? 

바로 이름에 오리가 들어가는 것입니다. 그것 말고는 서로간에 전혀 공통점이 없습니다. 자바와 자바스크립트와 유니티자바스크립의간의 관계도 이와 마찬가지입니다. 서로간에 전혀 공통점이 없다고 봐도 무방합니다. 문법이 비슷해보이지만 실제로 파고들어보면 전혀 다른 언어들입니다. 그러므로 그런거 신경쓰지 마시고 그냥 C#으로 사용하시는 것을 추천드립니다.



Posted by ozlael
,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
많은 분들이 유니티4의 프로젝트를 유니티5로 마이그레이션 하는 것에 대하여 걱정을 하고계십니다. 하지만 업그레이드 과정은 복잡할 게 없습니다. 물론 설정을 좀 건드려줘야 하는 부분들도 생기고 귀챦은 일들도 생기긴 하지만 그리 큰 노력이 들지는 않습니다. 또한, PBS 및 실시간 GI때문에 무조건 느려지는 것이 아닌가 걱정도 하시는 분들도 계십니다. 하지만 PBS가 아닌 기존 레거시 셰이더도 이용 가능하며 실시간 GI도 사용 여부를 선택 가능하므로 성능 하락에 대한 걱정은 안하셔도 됩니다. 
어서와 유니티5는 처음이지?

그래서 제가 개인적으로 유니티 4.6으로 만들고 있던 프로젝트를 유니티5로 업그레이드하고 그 과정을 기술하고자합니다. 물론 매우 작은 프로젝트라서 큰 도움이 되실런지는 모르겠습니다. 다만 참고 자료정도로 생각해주시면 감사하겠습니다. 유니티5로 빌드한 프로젝트를 구글 플레이에 올려두었습니다. 아직 테스트 버젼이므로 게임의 완성도는 신경쓰지 마시고 작동 여부정도만 확인해보시면 될 것 같습니다 :)

우선 유니티5로 업그레이드 하기 전에 반드시 프로젝트를 백업해두시길 바랍니다. 업그레이드를 시작하면 돌이킬 수가 없으므로 혹시 모를 불상사는 항상 대비해두셔야합니다. 백업 후 유니티5를 실행하시면 유니티4와는 다르게 프로젝트를 선택하는 창이 먼저 뜹니다. 
업그레이드하려는 프로젝트를 선택하면 잠시 후 다음과 같이 업그레이드를 진행하겠다는 창이 뜹니다. upgrade버튼을 눌러서 업그레이드를 진행합니다. 

이후 유니티가 업그레이드를 알아선 진행합니다. 시간이 좀 지난 후 다음과 같은 창이 뜹니다. 유니티5로 넘어오면서 스크립트 API들이 변경 된 사항들이 있습니다. 이를 자동으로 바꿔주겠단 소리인데 Go Ahead를 선택하여 진행해줍니다. 
이 과정들이 매우 오랜 시간이 소요됩니다. 침착함을 가지고 커피한잔의 여유를 즐기세요 :)


오류 사항들

업그레이드가 완료되고나면 수 많은 에러 상황들이 발생할 것입니다. 그런것 없이 완벽하게 마이그레이션 되었다면 당장 꿈에서 깨어나세요 용사여! 꿈이 아니라면 축하드립니다. 당장 사표 한장 집어던지고 뛰쳐나가서 로또 한장 사세요 :)

맨 처음 눈에 들어오는 것은 스카이박스일것입니다. 스카이박스의 십중팔구는 이미지가 정상적으로 나오지 않을 것입니다. 유니티5에서는 스카이박스가 HDR로 그려지는데 유니티4에서 설정했던 LDR 스카이박스를 가져오면 아래와 같이 깨집니다. 이는 간단히 수정 가능합니다. 해당 스카이박스를 선택 후 inspector창에 나오는 Fix now 버튼을 누르시면 해결됩니다.

셰이더에 문제가 발생하시는 분도 계실 수 있습니다. 유니티에서 기본적으로 제공하는 셰이더만 이용한다면 문제가 발생하지 않으실겁니다. 하지만 커스텀 셰이더를 이용하는 경우는 라이팅이 정상적으로 그려지지 않을 수 있습니다. 저같은 경우는 다음과 같이 이상하게 셰이더가 망가져 보였습니다. 
이는 셰이더로 넘겨주는 normal값때문에 발생하는 문제입니다. 유니티5에서는 셰이더로 넘어오는 vertex의 normal값이 메시의 스케일링이 적용되서 넘어옵니다. 따라서 항상 길이가 1이라는 보장이 없습니다. 또한, unity_Scale.w가 작동하지 않습니다. 그렇기때문에 셰이더에서 normalize를 해주어야 합니다. 이는 binormal, tangent 모두 동일하게 적용됩니다. 또한, 기존에는 라이트의 atten 값을 두배로 뻥튀기해줘야만 했는데 이제는 그러지 않아도 됩니다. 기타 셰이더 관련 가이드를 참고하여 수정하시면 정상적으로 보입니다. ( 본 포스팅 마지막의 링크들 참고)

오브젝트의 스케일이 틀어져있는 경우도 존재합니다. 기존에는 FBX 익스포트 시 적용 된 스케일이 정상적으로 적용되지 않는 문제가 있었는데 이제는 정상 반영이 됩니다. 따라서 FBX 메시들의 스케일이 변경되는 것 들이 있습니다. FBX import 설정에서 스케일을 변경시켜주면 됩니다.
간혹 skinned mesh가 깨지는 경우도 있습니다. 서로 다른 레거시 에니메이션과 메시를 휴머노이드로 조합한 이루어진 오브젝트가 간혹 깨지는 경우가 있습니다. 아직 정확한 조건은 확인하지 못하였습니다. 이런 경우는 답이 없습니다만 매우 드문 케이스이므로 크게 걱정하지는 않으셔도 될 듯 합니다.
유니티5에서는 라이트맵 솔루션이 비스트에서 인라이튼으로 바뀌었습니다. 따라서 라이트맵 관련 설정을 다시 손봐주셔야합니다. 기존 버젼에서부터 만들던 모바일 프로젝트라면 실시간 GI를 사용하지 않는 경우가 대부분일테니 Baked GI 외 다른 옵션들은 다 꺼주시면 됩니다. 
GI 관련하여 라이팅 타입 속성이 추가되었습니다. 라이팅 오브젝트의 인스펙터창에 Baking 타입을 설정 할 수 있는 콤보 박스가 있습니다. Baked로 설정해두면 실시간 라이팅에는 반영되지 않고 라이트맵에만 반영되는 라이트가 됩니다. 제 프로젝트의 경우에는 실시간 라이팅을 전혀 사용하지 않고 IBL만 사용하므로 모든 라이트를 Baked로 설정해두었습니다.

또한, 오브젝트의 인스펙터 창에서도 속성들이 추가된 것 들이 있으니 이를 건드려줘야 합니다. Cast Shadow, Receive Shadows, Use Light Probes는 기존에도 있는 속성이였으나 기존 설정이 날라갔을 수도 있으니 한번 더 확인해줘야합니다. Reflection Probes는 새로 생긴 속성이므로 체크 해제해주어야 의미없는 성능 소모를 줄일 수 있습니다. 

유니티5 에서는 메카님이 대폭 개선되었습니다. 기존 버젼 호환이 최대한 작업이 되어있긴 하지만 트랜지션이 누락되는 경우도 가끔 존재합니다. 또한 state에 Write Defaults라는 속성이 생김으로 인해서 기존에 예측했던 동작과 다르게 보이는 경우도 존재할 수 있습니다. 그냥 메카님은 전체적으로 한번 검토해보시는 것이 좋을 듯 합니다.


기타

제 프로젝트는 이러한 수정 사항들이 있었습니다만 프로젝트마다 수정 필요 사항들이 각기 다를것입니다. 더 자세한 내용은 아래 업그레이드 가이드들을 참고 바랍니다.

공식 메뉴얼 (영문) :
한글 번역본 :

결론적으로 말씀드리자면, 작은 프로젝트 혹은 개발 초기 단계의 프로젝트들은 유니티5로 업그레이드 시 큰 무리는 없어보입니다. 유니티 직원으로서는 무조건 유니티5로 업그레이드 하라고 말씀드리고 싶지만, 현실적으로는 규모가 크거나 출시 임박인 프로젝트는 한번 검토를 해보시는 것이 좋을 듯 합니다.
뭐 어찌되었든 유니티5의 세계로 오신 것을 환영합니다!


Posted by ozlael
,