React-Native Unity 임베딩 하기

갓수·2023년 3월 23일
0

react-native

목록 보기
1/1
post-thumbnail

react native에 unity project 임베딩 하기

혹시나 같은 환경에 있는 개발자에게 삽질의 시간을 조금이라도 줄여주고 싶은 마음에..

해당 게시글은 M1 mac 기준으로 작성되었습니다.

1. android

사용 라이브러리 : react-native-unity-play

url : https://www.npmjs.com/package/react-native-unity-play/v/0.1.6

2. ios

사용 라이브러리 : @azesmway/react-native-unity

url : https://github.com/azesmway/react-native-unity

RN version : 0.68.2

android는 에뮬레이터로 가능하지만 ios는 실제기기가 있어야만 동작합니다.

android 적용 방법

unity project export 설정

  1. Export Project -> 체크 선택
  2. Player Settings -> Resolution and Presentation -> Start in fullscreen mode -> 체크 해제
  3. Player Settings -> Resolution and Presentation -> Render outside safe area -> 체크 해제
  4. Scripting Backend -> IL2CPP
  5. Api Compatibility Level -> .NET Standard 2.0
  6. Target Architectures -> ARM64만 체크

해당 unity 프로젝트 빌드 파일은 rn root 폴더에 unity라는 이름으로 경로를 만들어준 후 복사붙여넣기 하면 됨

react native project 설정

npm install react-native-unity-play --force
  1. android/app/libs 디렉토리 만들기

  2. 라이브러리 설정 파일 옮기기
    <project_name>/unity/builds/android/unityLibrary/libs/*
    -> android/app/libs

  3. android/app/build.gralde에 ndk 코드 넣기

defaultConfig {
    ...
    ndk {
        abiFilters "armeabi-v7a", "arm64-v8a"
    }
}

4.android/settings/gradle에 코드 넣기

include ':unityLibrary'
project(':unityLibrary').projectDir=new File('../unity/unityLibrary')

두번째 줄은 본인의 경로에 맞춰서 집어넣으면 됩니다.

  1. android/app/build.gradle dependencies 부분에 코드 넣기
implementation project(':unityLibrary')
  implementation files("${project(':unityLibrary').projectDir}/libs/unity-classes.jar")
  1. android/app/src/main/res/values/string.xml 코드 추가
<string name="game_view_content_description">Game view</string>
<string name="unity_root">unity_root</string>
  1. AndroidManifest.xml의 MainActivity 업데이트하기
<application
  ...
  android:extractNativeLibs="true" 

<activity
  android:name=".MainActivity"
  ...
  android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
  android:hardwareAccelerated="true"
>
  1. <project_name>/unity/builds/android/unityLibrary/src/main/AndroidManifest.xml안의 해당 코드 제거하기
<intent-filter>...</intent-filter>
  1. android/gradle.properties 코드 추가하기
unityStreamingAssets=.unity3d

10.build.gralde에 코드추가하기

allprojects {
    repositories {
        flatDir {
            dirs "$rootDir/app/libs"
        }
  1. 예시 코드
import { StyleSheet, View, Dimensions, Button, Platform, Text } from "react-native";
import UnityView, {
  UnityModule,
  UnityResponderView,
} from 'react-native-unity-play';
import { useState } from "react";

const {width, height} = Dimensions.get('window');

const App = () => {
  return (
    <>
    <View>
      <Text>RNPROJECT</Text>
      <UnityView
        fullScreen={true}
        style={{width: width, height: height}}
      />
    </View>
    </>
  );
};
export default App;

에러 해결 방법

1. ndk 관련 해결 방법

android/local.properties에 ndk 경로 지정

필자는 unityhub의 ndk 경로를 지정해주어서 해결함

2. libil2cpp 에러 해결 방법

unity/unityLibrary/build.gradle BuildIl2Cpp 함수 부분 코드

def BuildIl2Cpp(String workingDir, String targetDirectory, String architecture, String abi, String configuration) {
    exec {
        commandLine(workingDir + "/src/main/Il2CppOutputProject/IL2CPP/build/deploy/netcoreapp3.1/il2cpp",
            "--compile-cpp",
            "--avoid-dynamic-library-copy",
            "--profiler-report",
            "--libil2cpp-static",
            "--platform=Android",
            "--architecture=" + architecture,
            "--configuration=" + configuration,
            "--outputpath=" + workingDir + targetDirectory + abi + "/libil2cpp.so",
            "--cachedirectory=" + workingDir + "/build/il2cpp_"+ abi + "_" + configuration + "/il2cpp_cache",
            "--additional-include-directories=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/external/bdwgc/include",
            "--additional-include-directories=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/libil2cpp/include",
            "--tool-chain-path=" + android.ndkDirectory,
            "--map-file-parser=" + workingDir + "/src/main/Il2CppOutputProject/IL2CPP/MapFileParser/MapFileParser.exe",
            "--generatedcppdir=" + workingDir + "/src/main/Il2CppOutputProject/Source/il2cppOutput",
            "--baselib-directory=" + workingDir + "/src/main/jniStaticLibs/" + abi,
            "--dotnetprofile=unityaot")
        environment "ANDROID_SDK_ROOT", getSdkDir()
    }
    delete workingDir + targetDirectory + abi + "/libil2cpp.sym.so"
    ant.move(file: workingDir + targetDirectory + abi + "/libil2cpp.dbg.so", tofile: workingDir + "/symbols/" + abi + "/libil2cpp.so")
}

3. A problem occurred configuring project ':react-native-unity-play'

jcenter없어짐으로 인한 오류
node_modules/react-native-unity-play/android/build.gradle에서 변경
 repositories {
        mavenCentral()
        //jcenter()
        maven { url "https://maven.google.com" }
    }

ios 적용 방법

unity project export 설정

Player Settings -> Strip Engine Code -> 체크 해제

해당 unity 프로젝트 빌드 파일은 rn root 폴더에 unity/builds/ios 라는 이름으로 경로를 만들어준 후 복사붙여넣기 하면 됨

yarn add @azesmway/react-native-unity

cd ios
pod install
이후에 xcode로 project 열기

  1. 프로젝트 루트에서 Add Files to "your project"

  1. unity/builds/ios/Unity-iPhone.xcodeproj 추가

  1. 이후 Unity-iPhone 프로젝트 Data 클릭 후 Target Membership -> UnityFramework 체크

  1. Libraries/Plugins/iOS의 NativeCallProxy.h Target Membership -> project에서 Public으로 변경
    만약 해당 경로가 없다면 새로 추가하여 해당 파일을 넣어줘야함

  2. 프로젝트 루트클릭 후 General -> Framework, Libraries, and Embedded Content에 UnityFramework.framework 추가

  1. Build Phases에 Link Binary With Libararies에서 UnityFramework.framework 삭제
  2. Embed Frameworks 안의 파일들 Compile Sources로 drag&drop으로 이동

  1. Project -> scheme -> Edit scheme 에 UnityFramework 추가 후 Build Order Manual Order로 변경

    UnityFramework가 먼저 빌드되어야 함

  1. Run 설정에서 Debug executable 체크해제
    해당 부분 체크 해제하지않으면 빌드 완료되고 launchscreen에서 멈춰있음

예제 코드

import { StyleSheet, View, Dimensions, Button, Platform, Text } from "react-native";
import UnityView from '@azesmway/react-native-unity';

const {width, height} = Dimensions.get('window');

const App = () => {
  return (
    <>
      <View>
        <Text>RNPROJECT</Text>
        <UnityView
          style={{width: width, height: height}}
        />
      </View>
    </>
  );
};
export default App;

에러 해결 방법

1. cannot find nativeCallProxy

nativeCallProxy.h파일을 public으로 설정해야함

2. 빌드 이후에 unityFramework 라이브러리를 찾을 수 없다.

해당 부분에 추가되어있는지 체크

nativeCallProxy.h,nativeCallProxy.m 파일

참고 링크 : https://github.com/azesmway/react-native-unity
https://www.npmjs.com/package/react-native-unity-play/v/0.1.6

profile
중요한건 꺾이지 않는 마음

2개의 댓글

comment-user-thumbnail
2023년 8월 22일

안녕하세요 혹시 유니티 프로젝트와 rn 프로젝트 명이 같아야할까요 ?

혹시 유니티 버전은 몇버전 사용하셨는지 알 수있을까요.. 감사합니다.

1개의 답글