Unity 게임 개발 중 안드로이드 폰에서 안드로이드만의 특정 기능이 필요할 때가 있는데 이때 안드로이드 JAR 플러그인 생성 방법을 알아보도록 하겠습니다.
안드로이드 스튜디오에서 새프로젝트 생성 후 Empty Activity 선택합니다.
프로젝트 이름, 패키지이름,프로젝트 위치 등을 지정해주고 Finish 해줍니다.
Unity Activity를 상속을 받으려면 Unity 라이브러리를 프로젝트에 포함시켜야 합니다.
아래 공식 문서에서 위치를 확인 후 본인 pc에 맞게 찾으면 됩니다.
https://docs.unity3d.com/kr/2018.1/Manual/AndroidUnityPlayerActivity.html
저의 PC 에서는 Windows 기준에서 아래 2군데에 존재합니다.
Mono
C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\Classes\classes.jar
IL2CPP
C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Development\Classes\classes.jar
자신의 빌드 상황에 맞게 선택하면 될 거 같습니다. (참고로 2개 파일 winmerge 프로그램 비교해보면 바이너리 파일이 동일하다고 나오는데 두 개다 같은 거 아닌가 싶습니다.)
저는 Mono에 classes.jar 파일을 선택해서 사용하였습니다.
파일 복사 후 아래 경로의 libs 폴더에 붙여 넣기 하면 아래와 같이 창이 뜨는데 이때 ok 버튼을 눌러줍니다.
아래와 같이 classes.jar 파일이 복사됩니다.
아래와 같이 build.gradle(Module: app)을 열어서 맨 위에 apply plugin: 'com.android.application'에서 apply plugin: 'com.android.library'로 변경해줍니다. 이후 아래 3곳을 주석처리 해준 후 Sync Now를 눌러줍니다.
//applicationId "com.test.aaa.plugintest"
//versionCode 1
//versionName "1.0"
MainActivity.java 페이지로 이동 후 아래와 같이 상속 부분을 UnityPlayerActivity로 변경해주면 에러 없이 상속받을 수 있게 됩니다. 아래 예제 코드는 현재 폰의 통신상태가 연결되어있는 국가코드를 받아오는 코드를 넣었습니다. 이렇게 만든 GetCountryCode() 함수를 Unity에서 호출하여 사용할 예정입니다.
그리고 setContentView(R.Layout.activity_main);은 주석처리하였습니다.
package com.test.aaa.plugintest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.unity3d.player.UnityPlayerActivity;
public class MainActivity extends UnityPlayerActivity {
static String mCountryCode = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
TelephonyManager tm = (TelephonyManager)this.getSystemService(this.TELEPHONY_SERVICE);
String countryCodeValue = tm.getNetworkCountryIso();
if (countryCodeValue != null) {
mCountryCode = countryCodeValue.toUpperCase();
Log.d("PluginTest", "countryCodeValue.toUpperCase() : " + mCountryCode);
}
}
public static String GetCountryCode() {
Log.d("PluginTest", "GetCountryCode() : " + mCountryCode);
return mCountryCode; //KR
}
}
이제 코드가 완성되었으므로 jar 파일을 생성해 보겠습니다.
우선 아까 수정하였던 build.gradle(Module: app) 파일을 열어서 맨 아래줄에 아래와 같이 추가해 줍니다.
그리고 다시 Sync Now 해줍니다.
task deleteObjectJar(type: Delete){
delete 'release/PluginTest.jar'
}
task exportJar(type: Copy){
from('build/intermediates/packaged-classes/release/')
into('release/')
include('classes.jar')
rename('classes.jar', 'PluginTest.jar')
}
exportJar.dependsOn(deleteObjectJar, build)
from 경로는 build/intermediates/packaged-classes/release/ 이렇게 했을 때 jar 파일이 생성되지 않았다면
build/intermediates/bundles/release/ 이렇게 해주면 됩니다.
Gradle -> PluginTest -> app -> Tasks -> other -> exportJar를 더블클릭해줍니다.
빌드가 완료 후 아래와 같이 BUILD SUCCESSFUL 메시지가 뜨고 D:\client\PluginTest\app\release로 이동하게 되면 PluginTest.jar 파일이 생성된 것을 확인할 수가 있습니다.
PluginTest.jar 파일을 유니티가 설치된 Assets\Plugins\Android에 넣어줍니다.
이제 유니티에서 안드로이드에서 만든 GetCountryCode() 함수를 아래와 같이 코드 생성하여 빈 오브젝트에 붙여서 클릭 시 국가코드를 안드로이드에서 가져올 수 있도록 하겠습니다.
using UnityEngine;
public class PluginTest : MonoBehaviour
{
public static PluginTest Static;
private AndroidJavaObject javaObj;
private void Awake()
{
Static = this;
DontDestroyOnLoad(gameObject);
}
void OnDestroy()
{
Static = null;
}
void Start()
{
javaObj = new AndroidJavaObject("com.test.aaa.plugintest.MainActivity");
if (javaObj != null)
{
Debug.Log("====================javaObj != null");
}
else
{
Debug.Log("====================javaObj == null");
}
}
public void ONCLICK_GETCOUTNRY()
{
Debug.Log("<PluginTest> ONCLICK_GETCOUTNRY()");
var Code = javaObj.CallStatic<string>("GetCountryCode");
Debug.Log("ONCLICK_GETCOUTNRY() Result = " + Code);
}
}
기존에 Assets\Plugins\Android\AndroidManifest.xml 파일을 열어서 com.unity3d.player.UnityPlayerActivity를 안드로이드 스튜디오에서 메인 액티비티인 com.test.aaa.plugintest.MainActivity로 변경해줍니다.
변경 전
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name">
변경 후
<activity android:name="com.test.aaa.plugintest.MainActivity" android:label="@string/app_name">
수정 결과는 아래와 같습니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.norion.p007" xmlns:tools="http://schemas.android.com/tools" android:installLocation="preferExternal">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
<application android:name="androidx.multidex.MultiDexApplication" android:theme="@style/UnityThemeSelector" android:icon="@mipmap/app_icon" android:label="@string/app_name" android:usesCleartextTraffic="true">
<activity android:name="com.test.aaa.plugintest.MainActivity" android:label="@string/app_name"> <!-- ================== 기존 코드에서 여기에 name 부분만 바꿔줬음 -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
<activity android:name="com.facebook.unity.FBUnityLoginActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<activity android:name="com.facebook.unity.FBUnityDialogsActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<activity android:name="com.facebook.unity.FBUnityAppLinkActivity" android:exported="true" />
<activity android:name="com.facebook.unity.FBUnityDeepLinkingActivity" android:exported="true" />
<activity android:name="com.facebook.unity.FBUnityGameRequestActivity" />
<activity android:name="com.facebook.unity.FBUnityCreateGameGroupActivity" />
<activity android:name="com.facebook.unity.FBUnityJoinGameGroupActivity" />
<activity android:name="com.facebook.unity.AppInviteDialogActivity" />
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="fb772073929601405" />
<provider android:name="com.facebook.FacebookContentProvider" android:authorities="com.facebook.app.FacebookContentProvider772073929601405" android:exported="true" />
<activity android:name="com.facebook.unity.FBUnityGamingServicesFriendFinderActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="true" />
<meta-data android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled" android:value="true" />
</application>
</manifest>
빌드 후 테스트 결과 버튼 클릭 시 국가코드를 제대로 받아 오는 걸 확인할 수 있다.
이상으로 유니티에서 안드로이드 JAR Plugin을 생성하여 안드로이드에서만 사용할 수 있는 코드를 작성해 보았습니다.
[참고]
확인 결과 안드로이드 프로젝트 생성 시 패키지 네임과 유니티 설정창에 패키지 네임이 굳이 같을 필요는 없는 거 같습니다.
[확인해볼 사항]
mono에 있는 classes.jar로 사용하고 유니티 빌드에서는 IL2CPP로 빌드했을 때 문제없는지 확인해보자.
그리고 반대 상황도 확인해 보자.
이유는 mono가 유니티 빌듯이 속도가 빨라서 테스트 상황에서는 mono로 빌드를 자주 하는데 라이브 버전에서는 IL2CPP로 빌드를 해야 한다. 이럴 경우 또 안드로이드 라이브러리 바꿔서. jar 파일을 다시 뽑아야 하는 번거로움이 있기 때문에 classes.jar 파일 맞지 않아도 상관없는지 확인해 볼 필요가 있다. 그런데 두 개 파일을 winmearg 프로그램으로 비교해보면 바이너리 파일이 같아서 문제없을 거 같긴 하다.
'Programming > Unity' 카테고리의 다른 글
IOS 시뮬레이터 빌드 (0) | 2020.10.14 |
---|---|
Error running cocoapods. please ensure you have at least version 1.0.0 (0) | 2020.08.24 |
최적화되지 않은 APK (0) | 2020.07.13 |
안드로이드 앱 서명키 및 업로드 키 (0) | 2020.07.13 |
Assets\GooglePlayGames\Editor\NearbyConnectionUI.cs(137,17): error CS0234: The type or namespace name 'VersionHandler' does not exist in the namespace 'Google' (are you missing an assembly reference?) (0) | 2020.07.06 |
댓글