애초의 목표는 Android 앱에 Unity3d 뷰를 embedding 하는 것이었는데, 이걸 하려면 기본적으로 aar과 unity와의 관계에 대한 공부가 필요한 것 같습니다. Unity3d에서 직접 apk를 만들 수도 있지만, 좀 더 세부적인 설정을 변경하여 빌드하기 위해 프로젝트를 export하여 Android Studio에서 프로젝트를 빌드 할 수도 있습니다.
아무튼, 이런 관계들 중에서 사용 할 수 있는 것이 무엇인지 확인을 해둬야 필요할 때 사용 할 수 있는 기술이 무엇인지 판단하고 개발 방향을 정할 수 있기 때문에 무엇이든 한번 알아보기로 했습니다.
여러가지 자료를 찾아보고 시도 해 봤는데, 결코 쉽지 않았습니다.
Android Studio나 Unity3d의 프로젝트 설정이나 빌드 설정을 할 일이 그다지 없어 작은 문제가 생기면 어느 부분에서 발생하는지 알 수가 없었습니다. KeyStore까지 해줘야 하는지 결코 몰랐죠.
그렇게 여러 자료를 보고 시도하다가 좌절하고, 다시 해보자며 영어로 된 유튜브 자료 봐 두었던 것을 보려고 하다가, 거의 비슷한 내용이 한글로 되어 있는 것을 보고 한번 따라 가 보기로 했습니다.
참고 프로젝트
참고한 동영상은 아래 채널입니다. 4년 전에 올리신 영상인데 지금은 훨씬 더 전문가의 포스를 풍기고 좋은 영상을 많이 올리고 계신 것 같네요.
https://www.youtube.com/@nkstudio9161
NK Studio의 유니티 스페셜 테크닉
국내 유니티를 사용한 코딩 유튜브 체널! 회사 업계에서 사용할만한 기술도 소개합니다
www.youtube.com
참고했던 영상은 아래 영상입니다. 본 영상을 직접 보면서 따라 해 보는 것도 좋을 것 같아요.
https://www.youtube.com/watch?v=B7a6xpMXDYE
아래는 영어로 된 것인데, 재생목록이나 내용이 거의 비슷하네요. Context 대신 Activity를 사용하신 것을 보면, 나름 최신 환경에서 업데이트 하시면서 쓰신 것 같아요. . NK Studio에는 4년 전에 올라왔고, 아래는 1년 전이니까 한국분 것이 오리지널인 것 같습니다. 훌륭하십니다.

https://www.youtube.com/watch?v=6u7FV-e6nUc&list=PLgdJs67VIHij7g5vf-AYChkSNn8X73ECS
AAR 생성
Android Studio에서 AAR을 생성 해 보겠습니다. 앞에서 AAR 만들어 사용하는 글을 썼는데, 굳이 Empty Activity 템플릿 프로젝트를 만들 필요가 없이 그냥 No Activity로 했어도 되었네요. 이것저것 많이 배웁니다.
프로젝트 생성
New project / No Activity
프로젝트 이름을 정하고, 이 때 Minimum SDK 버젼은 좀 신경을 써야 합니다. 실제로 혼자서 영어 버젼 보면서 할 때 이 버젼 문제 때문에 안되는 것인가 싶었는데, 정말 중요한 부분인 것이 맞네요. 영어 영상에는 이런 자세한 설명이 나오지 않는데, 원본 영상에는 도움이 되는 말씀을 많이 해주시는 것 같습니다.
Module 생성
아래 순서에 따라 모듈을 만듭니다.
app / New / Module
요런 방법도 된다는 것도 겸사 겸사 배웠습니다.
AAR 설정창에서 Package name은 나중에 Unity에서 불러올 때 사용하는 것이니 잘 작성 해 줍니다.
그리고, 저기 Minimum SDK 잘 챙겨야 합니다.
영어 영상에서는 없었던 내용인데, 아래와 같이 불필요한 내용을 지우라는 말씀도 해주셔서 좋았습니다.
Module 확인 후 androidTest/ test는 삭제
그리고 AAR의 실제 내용이 될 라이브러리를 JAVA Class로 구현하기 위해 JAVA Class를 하나 추가합니다.
처음에 이런 공부를 할 때는, 이게 원래 지정 된 문구인지, 내가 설정한 값에 의해서 결정 된 것인지 잘 구분이 안되는 경우가 많습니다. 그래서, 일부러 클래스 이름에 Class라고 적어서 잘 구별 되도록 해 두고 진행하였습니다.
Class 내용은 아래와 같습니다.
Instance를 Singleton 으로 만들었습니다. 영상에서는 함수를 private로 하셨는데, 저는 외부에서 호출하는 것이라 public으로 하는 것이 맞을 것 같아서 public으로 했어요. private으로 해도 되는지는 확인 해 보지 않았습니다. 코드 자체가 복잡하지는 않고, singleton 구현 내용과 토스트 띄우는 내용이 거의 대부분 입니다.
package com.red.unitypluginaddtoast;
import android.content.Context;
import android.widget.Toast;
public class UnityPluginAARClass {
// Instance
private static UnityPluginAARClass m_instance;
public static UnityPluginAARClass instance() {
if(m_instance == null) {
m_instance = new UnityPluginAARClass();
}
return m_instance;
}
// Context
private Context context;
public void setContext(Context ct) {
context = ct;
}
public void ShowToast(String msg, int length) {
if( length == 0) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
}
}
}
이제 코드가 준비되었으니, 빌드를 하여 AAR 파일을 만듭니다.
요렇게 만들어진 AAR을 Unity에서 사용하게 됩니다.
Unity
Unity 프로젝트는 영어 영상 보면서 하다가 잘 안되서 좌절하고 있던 중이었어요. 그 프로젝트 기반에 새 AAR을 추가하고, 새 Script를 추가하여 준비했습니다.
아래와 같이 Plugins 폴더와 그 하위에 Android 폴더를 만들어 AAR 파일을 넣습니다. 이 때 폴더 이름을 꼭 저렇게 해야하는지도 사실 좀 궁금한데 확인 해 보지는 않았습니다. 영문 영상을 따라 하느라 좀 지쳐서..ㅋㅋ
AAR 파일을 추가하고~
새로운 스크립트 파일도 추가합니다.
스크립트 내용은 아래와 같습니다.
그런데, 영어 영상과 내용이 좀 달라요. 이 부분은 영상 내용을 참고 하시는 것이 큰 도움이 될 것 같습니다.
이 부분에 특히나 항상 같은 내용으로 써야 할 것과 내가 입력한(Android에서...) 내용에 따라서 결정되는 것이 섞여 있어서 관련 된 내용을 들으면 도움이 될 것 입니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AndroidPlugin : MonoBehaviour
{
//Android Java Objects
private AndroidJavaObject UnityActivity;
private AndroidJavaObject UnityInstance;
// Start is called before the first frame update
void Start()
{
//Instantiation
AndroidJavaClass ajc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
UnityActivity = ajc.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaClass ajc2 = new AndroidJavaClass("com.red.unitypluginaddtoast.UnityPluginAARClass");
UnityInstance = ajc2.CallStatic<AndroidJavaObject>("instance");
UnityInstance.Call("setContext", UnityActivity);
}
// Update is called once per frame
void Update()
{
}
public void ToastButton()
{
ShowToast("Call from Unity", false);
}
public void ShowToast(string msg, bool isLong)
{
UnityActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
{
if (isLong == false)
{
UnityInstance.Call("ShowToast", msg, 0);
}
else
{
UnityInstance.Call("ShowToast", msg, 1);
}
}));
}
}
Unity에서도 min SDK version을 잘 맞춰줘야 합니다.
Project Setting / Player / Other / Identification에 Minimum API Level이 있습니다. 이것을 AAR에 있던 것과 같게 해줍니다.
(만약, 상용 라이브러리를 쓰려면 어떻게 맞춰 줄 수 있을지 좀 궁금해지네요.)
이것이 맞지 않으면, 아래와 같은 오류가 날 수도 있습니다.
빌드 & 실행
기대를 안고 빌드를 했는데, Key Store 문제로 생겼던 문제가 또 생겼습니다. 급 좌절....
일단 새로운 Key Store를 만들어서 했는데도 뭐가 또 안되고...
전에 못봤던 아래 경고창이 뜨기에 가만히 읽어보니, IL2CPP와 ARM64를 적용해야 하는 것 같네요.
요렇게 설정하고 빌드를 하니까, 하~~~~~~~~~~~~안참을 빌드를 했습니다.
희망적인 현상이죠~
결과는 아래와 같이 버튼을 누르면 아래쪽에 토스트가 발생하는 것을 볼 수 있습니다.
이 코드를 기본 틀로 잡아서 여러가지 응용과 확장을 해 나가보면 좋을 것 같습니다.
시간 정보에서 분과 초를 더하여 화면에 출력하는 샘플도 한번 해봤습니다. Toast를 띄울 때는 runOnUiThread를 사용했어야 했는데 이렇게 간단한 함수를 직접 호출해도 문제가 없는 것 같습니다. 그런데, 자칫 잘못하면 ANR을 띄울 가능성이 있으니 주의 해야 될 것 같아요.
public void onClickAdd()
{
Debug.Log("Button is pressed.");
int minutes = System.DateTime.Now.Minute;
int seconds = System.DateTime.Now.Second;
int sum = minutes + seconds;
if (utilClassInstance != null)
{
sum = utilClassInstance.Call<int>("AddInt", minutes, seconds);
string result = string.Format("{0} + {1} = {2}", minutes, seconds, sum);
Debug.Log(result);
resultText.text = result;
}
else
{
Debug.Log("Instance is null");
resultText.text = "Initance is null";
}
}
결과는, (동영상 크기 조정 하는 방법을 좀 알아봐야 될 듯 하네요.)
위 내용은 Android에서 구현한 라이브러리를 Unity3d에서 사용한 경우인데, 그 반대의 경우처럼, Unity3d의 Game화면을 Android에 넣고 상호 Interfacing 하는 방법도 알아가야겠습니다.
'공허의 유산 > 표현의 자유' 카테고리의 다른 글
[Unity3d/AssetBundle] 01. Asset Bundle 만들기 (0) | 2023.03.18 |
---|---|
Unity as Library - Unity를 Android에 Activity로 사용하기 (0) | 2023.03.06 |
(업데이트 된) AAR 만들기 & AAR 쓰기 (2) | 2023.03.02 |
[Unity3D/Shader] 06. 텍스쳐를 이용한 멀티 텍스쳐링 영역 설정과 물성 표현(Normal map, Metallic, Smoothness) (0) | 2023.02.23 |
[Unity3D/Shader] 05. 텍스쳐를 이용하여 불꽃 효과 내기 (6) | 2023.02.22 |
댓글