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

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를 완료했으면 이제 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파일로 되어있어서 터미널에서 커맨드라인으로 압축을 풀어줘야합니다. 우선 터미널을 열고 다운로드 받은 폴더로 이동합니다. 그 후 다음과같이 실행 권한을 추가해주고 압축을 풀어줍니다.


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

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


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

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


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


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


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

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


신고

이 글은 유니티 자습서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 폴더의 대부분의 오브젝트들이 첫 씬에서 보여질 필요가 없는 경우에는 효율적이지 못한 상황이 되는 것입니다.




신고

게임을 개발하는 과정에서 콘솔 로그를 출력하는 것은 필수적입니다. 당연히 유니티에서도 로그를 출력하는 함수가 존재하고 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


끗!


신고
  1. 붉은용기병 2016.09.07 11:48 신고

    좋을 글 감사합니다.
    프로젝트에 도움이 되었습니다.

+ Recent posts

티스토리 툴바