개발 관련/SW, App 관련

Unity용 Android의 plugin 만들기

소서리스25 2025. 2. 13. 17:32
반응형

Unity용 Android의 plugin 만들기

 

Unity와 Android 간 데이터 전송이 필요해서 플러그인을 만들어 볼 기회가 생겼다.

아직 한번도 안 만들어봐서 전혀 모르는 상태다. 

그동안의 Android Studio는 SDK용으로만 사용해서 그냥 설치만 되어 있던 것이다.

 

여러 사이트들에서 참고하였고 차근차근했는데 오류나 쏟아내고 왜 난 잘 안되는지 모르겠다. 어찌어찌해서 만들긴 했고 그 사항을 기록으로 남겨 놓는다. (아마도 버전이나 경로 여러 가지가 다 맞아야 하는 것 같다.)

 

그래서 간단한거라도 성공하면 응용할 수 있기에 한번 도전해 봤다.

기다리를 응용은 쉽지 않긴 한데 Git의 정보를 많이 활용할 것이어서 도전해 볼만한 것 같다.

 

참고로 관련된 상세한 내용을 더 잘 아는 다른 분들의 블로그를 참고하면 될 것이며, 여기서는 가장 단순하게 따라 하는 정도로만 진행한다.

 

그러면 먼저 개발 환경은 아래와 같다. 언제나 그렇듯 오래전에 설치해서 낮은 사양이다.

- Android Studio BumbleBee 2.1.1 Patch 1

- API : Min 24, Max 30

- Unity 2018.4.3

 

 

1. File > New > New Project

라이브러리로 만들 것이므로 비어있는 No Activity로 선택

 

 

2. Project 내용은 다음 그림과 같이 설정

특히 Minimum SDK는 나중에 Unity의 Minimum과 맞추기.

 

 

3. 모듈 생성하기 New > New Module > Android Library

Minimum SDK는 진행할 프로젝트에서 최소로 잡을 것으로 할 것. 더 낮아도 상관없으나 추후 Unity와 맞추고 Module name을 적절히 알아볼 수 있도록 정할 것.

 

 

4. Android의 메뉴를 Project로 변경

 

 

5. Unity의 Classes.jar을 복사하여 아까 만든 모듈인 unityPlugin/libs로 복사

Unity의 경로에서 \Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Classes 에 있다고 보면 된다.

 

 

6. 이제 Unity의 Classes.jar을 등록해 주려면 build.gradle를 클릭

dependencis에서 다음줄을 추가한다.

compileOnly files('libs/classes.jar')

 

이와 관련된 전체 코드를 다음과 같이 수정해 준다.

compileSdk와 targetSdk를 나중에 Unity에서 target SDK 하고 맞출 것이므로 나는 30으로 지정.

plugins {
    id 'com.android.library'
}

android {
    compileSdk 30

    defaultConfig {
        minSdk 24
        targetSdk 30

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    compileOnly files('libs/classes.jar')

    implementation 'androidx.appcompat:appcompat:1.7.0'
    implementation 'com.google.android.material:material:1.12.0'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.2.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
}

 

 

7. 이제 다음의 창의 우측상단에 있는 Sync Now를 진행

이상이 없다면 BUILD SUCCESSFUL가 뜬다.

 

 

 

8. 이제 주고받을 코드를 작성할 차례로 Project를 Android로 변경

먼저 아래 이미지처럼 2개는 제거해 준다. 충돌 가능성이 있다고 하니 삭제한다. 같이 선택하고 del 키를 누르면 한 번에 삭제 안되고 다시 위로 올라가는데 다시 선택해서 del키로 삭제한다.

 

 

9. Java Class 파일을 생성해 준다.

생성 이름은 임의로 unityPlugin으로 해주었다.

 

 

10. 아래의 코드를 적용한다.

package com.eduri.unityplugin;

import android.widget.Toast;
import com.unity3d.player.UnityPlayer;
import java.util.Random;

public class unityPlugin
{
    public static final String UNITY_OBJECT_NAME = "manager";

    public static void getRandomNumber()
    {
        int number = new Random().nextInt(100);
        UnityPlayer.UnitySendMessage(UNITY_OBJECT_NAME, "OnReceiveRandomNumber", String.valueOf(number));
    }

    public static void showToast(String message)
    {
        UnityPlayer.currentActivity.runOnUiThread(new Runnable(){
            @Override
            public void run()
            {
                Toast.makeText(UnityPlayer.currentActivity.getApplicationContext(), message, Toast.LENGTH_LONG).show();
            }
        });
    }
}

 

대충 내용을 설명하면 다음과 같으며 일단 모두 public static으로 되어 있는데, 이를 나중에 싱글톤으로 해줘도 된다.

 

 

함수는 2가지로 다음과 같다.

 

getRandomNumber() : 랜덤숫자를 실행하는 함수로 UNITY_OBJECT_NAME에서 지정한 객체("manager")를 Unity에서 찾으며 Unity 함수인 OnReceiveRandomNumber에 변수를 전달하는 역할을 한다. Unity함수에서 다시 소개.

 

showToast(String message)는 Unity로부터 문자를 받아서 그 문자를 토스트로 띄워준다.

 

 

11. 이제 .aar파일을 생성할 차례

아래의 이미지처럼 모듈을 Build 하면 된다.

 

 

12. Project로 변경 후 build > outputs > aar에 해당 플러그인이 생성 확인

 

 

13. 해당 aar 플러그인을 Unity에서 다음의 플러그인 폴더에 넣는다.

Assets > Plugins > Android 에 넣도록 한다.

그리고 다음과 같은 화면을 함께 구성한다. 여기서 Unity의 객체를 manager로 만들어 주고 해당 스크립트를 만들어서 적용해 준다.

 

 

14. 스크립의 코드는 다음과 같이 적용한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class manager : MonoBehaviour
{
    AndroidJavaClass _javaClass;
    public Text _text;

    void Start()
    {
        Screen.SetResolution(1280, 720, true);
        _javaClass = new AndroidJavaClass("com.eduri.unityplugin.unityPlugin");        
    }


    public void ButtonClick(int _num)
    {
        if (_num.Equals(0))
            ShowToast("Show Toast~~~");
        else
            GetRandomNumber();
    }


    public void ShowToast(string message)
    {
        _text.text = message;
        _javaClass.CallStatic("showToast", message);
    }


    public void GetRandomNumber()
    {
        _javaClass.CallStatic("getRandomNumber");
    }


    public void OnReceiveRandomNumber(string number)
    {
        _text.text = "Got random number:" + number;
        Debug.Log("Got random number:" + number);
    }
}

 

 

대충 Unity를 하는 분이라면 쉽게 알 수 있다.

 

UI에서의 버튼 2개에 각각 입력숫자 0, 1로 연결하여

상단버튼(0번)은 토스트 함수로 텍스트 전달한 후 안드로이드에서 해당 텍스트를 받아 안드로이드의 토스트로 호출한다.

그리고 하단버튼(1번)은 랜덤번호 함수를 실행하여 안드로이드의 랜덤번호 호출 함수를 실행하여 다시 Unity의 manager 객체를 찾아 생성된 랜덤 숫자를 manager의 OnReceiveRandomNumber 함수로 받아서 UI로 확인한다.

 

15. 이제 Unity에서 API를 설정(min 24, target 30) 한 뒤 빌드

결과는 다음과 같이 실행된다.

 

 

이정도면 다 까먹어도 다시 만들 수 있을 것 같다.;;;;;

 

반응형