본문 바로가기
Android

Android Studio+ Unity 적용 (1)

by Jiwon_Loopy 2025. 4. 5.
반응형

1. 적용 이유


진행중이던 프로젝트가 게이미피케이션 기반의 앱이었는데, 내부의 게임 내용들을 네이티브로 구현하였으나, 더 이상의 기능적 한계에 봉착하여 네이티브 코드를 걷어내고, 게임 부분을 게이미피케이션 분야에 특화된 유니티 툴을 이용하여 개발 후 모듈로 탑재하기로 하였다.

 

 

 

2. Unity Library


 

유니티는 기본적으로 export를 할 경우 안드로이드 플랫폼에서 사용할 수 있도록 설정할 수 있다. 유니티로 게이밍 부분을 개발해 주신 개발자 분께 참고할 블로그의 링크를 전달해드렸고, export한 패키지 내부의 Unity Library를 따로 빼내어 Android 프로젝트 내부에 탑재한 후 모듈로 지정해 주었다.

 

 

 

3. Unity에서 Export 하기


1. 유니티 에디터에서: Edit > Project Settings > Player > Android 설정
2. 여기서 Target API Level을 안드로이드 35(Android 15)에 맞게 설정
3. 최소 API 레벨도 적절히 설정 (보통 Android 6.0/API 23 이상 권장)

4. 유니티 프로젝트 내보내기
5. 유니티 에디터에서 프로젝트를 엽니다.
6. File > Build Settings를 선택
7. 플랫폼 목록에서 Android를 선택하고 필요하면 Switch Platform 버튼을 클릭
8. Export Project 옵션을 체크
9. Export 버튼을 클릭하고 내보낼 위치를 지정
이렇게 하면 유니티 프로젝트가 안드로이드 스튜디오에서 사용할 수 있는 모듈로 내보내진다.

 

이 부분은 Unity 개발을 하신 개발자 분께서 담당하셔서 이미지 파일을 준비하지 못했다.

 

 

 

4. Android Studio에서 Module로 만들기


 

1) unityLibrary 폴더 옮기기

 

프로젝트 루트 폴더에 유니티 라이브러리를 넣어주었다. 모듈 설정까지 마친 상태라 모듈이 적용된 모양으로 뜨지만, 해당 과정을 진행하지 않았다면 일반 템플릿 모양으로 뜰 것이다.

 

 

 

 

 

2) settings.gradle.kts 모듈 설정

include(":unityLibrary") // 이 부분
project(":unityLibrary").projectDir = File("C:\\Users\\PC\\Desktop\\MyApplication4\\unityLibrary") // 이 부분

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        flatDir {
            dirs(project(":unityLibrary").projectDir.resolve("libs"))
        } // 이 부분
        maven { url = java.net.URI("https://devrepo.kakao.com/nexus/content/groups/public/") }
    }
}

 

unityLibrary 폴더를 모듈로 만들기 위해 include와 함께 경로를 설정해준다.

repositories 내부에 flatDir을 통해 설정해 주어야 한다.

 

 

 

 

 

3) gradle.properties에 버전 기재

org.gradle.parallel=true
unityTemplateVersion=5
android.enableJetifier=true
unityStreamingAssets=.unity3d, google-services-desktop.json, google-services.json, GoogleService-Info.plist

 

해당 내용을 gradle.properties에 넣어준다.

 

 

 

 

 

4) strings.xml 

<string name="game_view_content_description">Game view</string>

 

이 구문은 참조한 블로그에서 넣어주라고 되어 있었는데 사용하지는 않는 것 같다.

 

 

 

 

 

5) build.gradle.kts (app 수준)

dependencies{
    implementation(project(":unityLibrary"))
}

 

앱 수준의 build.gradle에서 유니티 모듈을 포함시켜준다.

 

 

 

 

 

 

6) NDK 적용

 

자체 NDK를 사용하는 방법과, Android의 NDK를 사용하는 방법이 있었는데 나는 Android의 NDK 방법을 이용하였다.

 

Tool의 SDK Manager에 들어가게 되면,

 

해당 화면이 나오게 되는데 2번째 SDK Tools 탭을 눌러 NDK를 설치해주면 된다.

 

localproperties 파일에 기재해주는 방식이 있었지만, 해당 방법이 곧 사라진다는 경고 문구가 나와서, 안드로이드 build.gradle파일에 기재해 주었다.

 

 

해당 방법을 GPT의 도움을 받고자 하였는데, 옛날 방식을 알려주어 다른 방식을 택했다.

 

 

 

 

먼저 unityLibrary의 NDK 버전을 주석처리 해주고,

android {
    namespace "com.unity3d.player"
//    ndkVersion "29.0.13113456"
    compileSdk 35
    buildToolsVersion = "34.0.0"

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }

 

 

 

 

getNDKDir() 라는 NDK 디렉토리를 가저오는 함수를 만들어주었다.

def getNdkDir() {
    return android.ndkDirectory.toString()
}

 

 

 

 

그 후 아래처럼 추가한 함수를 적용해준다. 주석처리한 부분은 안정성 측면에서 선언한 함수로 대체해 준 것이다.

def BuildIl2CppImpl(String workingDir, String configuration, String architecture, String abi, String[] staticLibraries) {
    def commandLineArgs = []
    commandLineArgs.add("--compile-cpp")
    commandLineArgs.add("--platform=Android")
    commandLineArgs.add("--architecture=${architecture}")
    commandLineArgs.add("--outputpath=${workingDir}/src/main/jniLibs/${abi}/libil2cpp.so")
    commandLineArgs.add("--baselib-directory=${workingDir}/src/main/jniStaticLibs/${abi}")
    commandLineArgs.add("--incremental-g-c-time-slice=3")
    commandLineArgs.add("--configuration=${configuration}")
    commandLineArgs.add("--dotnetprofile=unityaot-linux")
    commandLineArgs.add("--usymtool-path=${workingDir}/src/main/Il2CppOutputProject/usymtool.exe")
    commandLineArgs.add("--profiler-report")
    commandLineArgs.add("--profiler-output-file=${workingDir}/build/il2cpp_${abi}_${configuration}/il2cpp_conv.traceevents")
    commandLineArgs.add("--print-command-line")
    commandLineArgs.add("--static-lib-il2-cpp")
    commandLineArgs.add("--data-folder=${workingDir}/src/main/Il2CppOutputProject/Source/il2cppOutput/data")
    commandLineArgs.add("--generatedcppdir=${workingDir}/src/main/Il2CppOutputProject/Source/il2cppOutput")
    commandLineArgs.add("--cachedirectory=${workingDir}/build/il2cpp_${abi}_${configuration}/il2cpp_cache")
//    commandLineArgs.add("--tool-chain-path=${android.ndkDirectory}")
    commandLineArgs.add("--tool-chain-path=${getNdkDir()}")

    staticLibraries.eachWithIndex {fileName, i->
        commandLineArgs.add("--additional-libraries=${workingDir}/src/main/jniStaticLibs/${abi}/${fileName}")
    }

 

 

 

 

app 수준의 build.gradle 파일에도 ndk를 명시해주었다.

android {
    namespace = "com.example.myapplication"
    ndkVersion = "25.2.9519653" // NDK 명시
    buildFeatures {
        dataBinding = true
    }

 

 

 

7) 액티비티로 실행

 

import com.unity3d.player.UnityPlayerGameActivity

 binding.unityBt.setOnClickListener{
            startActivity(Intent(requireContext(),UnityPlayerGameActivity::class.java))
        }

 

해당 라이브러리를 import 해준 후, 인텐트를 이용하여 실행해보니, 성공적으로 실행되었다.

 

 

 

 

 

5. 이슈


1. flatDir 방식

 

Groovy 방식과 Kotlin DSL 방식이 있는데 나는 코틀린 DSL 방식을 이용하였다.

flatDir {
    dirs = "${project(":unityLibrary").projectDir}/libs" // ❌ String 타입
}
// Groovy 방식

 

 

2. Project with path ':unityLibrary' could not be found in project ':app'.

 

유니티 라이브러리를 잦을 수 없다는 오류였다. 단순히 폴더만 넣는것이 아닌, 모듈로 설정을 해주어야 한다.

implementation(project(":unityLibrary"))

 

 

 

3.keepUnitySymbols.gradle 부재

 

유니티 버전이나 라이브러리에 따라 누락될 수도 있다하여 해당 부분을 주석처리 해주었다.

// apply from: "$rootDir/../shared/keepUnitySymbols.gradle"

 

 

 

4. Could not get unknown property 'unityStreamingAssets'

 

이 부분도 주석처리하여 해결할 수 있었다.

// noCompress = ['.unity3d', '.ress', '.resource', '.obb', '.bundle', '.unityexp'] + unityStreamingAssets.tokenize(', ')
noCompress = ['.unity3d', '.ress', '.resource', '.obb', '.bundle', '.unityexp']

 

 

 

5. [CXX1101] Location specified by android.ndkPath (C:/Program Files/Unity/Hub/Editor/6000.0.43f1/Editor/Data/PlaybackEngines/AndroidPlayer/NDK) did not contain a valid NDK and couldn't be used

 

꽤나 중요한 오류였다. 유니티의 경우 NDK Framework가 필요하다. NDK란, Native Develper's Kit의 약자로 쉽게 C/C++로 작성된 코드를 사용할 수 있게 해주는 기능이라고 생각하면 된다.

기본적으로 안드로이드 스튜디오에서는 깔려있지 않아서 직접 깔아주었다.

 

 

 

6. 파일의 크기가 너무 커서 깃허브에 올라가지 않는 이슈

 

깃허브에서 제한하는 용량을 넘어 push되지 않는 이슈가 있었는데, 빌드 산출물들을 gitignore에 추가해준 뒤, 최대한 코드 파일만 축소하여 업로드 해주었다.

# Unity 빌드 캐시, 바이너리
unityLibrary/build/
unityLibrary/src/main/jniLibs/
unityLibrary/src/main/IL2CppOutputProject/

 

 

 

7. Task :unityLibrary:buildIl2Cpp FAILED Execution failed for task ':unityLibrary:buildIl2Cpp'.

 

빌드 산출물을 제거하는 과정에서 누락된 파일이 생긴 것 같아서 현재 해결 중이다.

ndk 누락인 것 같은데 해당 깃허브에서는 local.properties 파일로 해결하고 있으나 위에서 설명했듯이 이미 설정은 완료한 상태이다. 현재 안드로이드에서 export한 파일을 맥에서 실행 시 나는 오류일 수도 있어 확인중이다.

 

Execution failed for task ':unityLibrary:BuildIl2CppTask'. · Issue #743 · juicycleff/flutter-unity-view-widget

Describe the bug When I try to create an android apk using the command 'flutter build apk --release' I get this error OS - Windows 11 Plugin Version - 2022.2.0 NDK version - 21.3.6528147 Flutter Ve...

github.com

 

 

 

 

 

 

 

 

 

 

모든 내용은 해당 PR에서 자세히 볼 수 있다. (깃 허브가 익숙하지 않아서 가독성이 떨어질 수 있음..)

 

Unity 연동 by hs-1971342-jiwonpark · Pull Request #66 · 9oormthon-univ/2024_DANPOONG_TEAM_45_FE

이슈 번호 : #63 추가 기능 UnityViewActivity 라이브러리 추가 LoginFragment 오른쪽 상단에 임시 버튼으로 연동 Unity Library 모듈 추가 NDK 버전 설정 ( 유니티 NDK -> 안드로이드 NDK )

github.com

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

출처


 

[Android] Unity와 Android 연동하기 | UnityPlayerActivity as subView

1. Unity Hub 다운받기 해당 링크에서 다운 받는다. 퍼스널 라이센스를 활성화 시켰다. 그냥 무료버전은 없는건가…? new project를 눌러보자 프로젝트가 생성되었다. 곧 각 항목에 대해 자세히 알아보

www.pinslog.com

 

(Unity) 유니티 프로젝트 안드로이드 스튜디오와 연동하는 법

유니티를 프로젝트를 안드로이드 스튜디오와 연동하는 방법을 정리해 보았습니다.​목차유니티 프로젝트 설정 및 export 하는 법안드로이드 스튜디오 유니티 프로젝트 연동 및 빌드     1. 유

jeongcook.tistory.com

 

728x90
반응형