Unity

iOS-Unity UAAL iOS와 Unity 사이 데이터 주고 받는 방법(feat swift)

CommitGuy 2025. 2. 4. 17:37

iOS에서 Unity를 라이브러리로 사용하는 uaal을 쓰게되면 당연하게도 ios project와 unity3d 사이에 데이터를 주고 받아야 하는 상황이 발생한다.

이럴 경우 어떻게 데이터를 주고 받을수 있는지 알아보도록 하겠습니다

 

이전에 uaal 을 어떻게 만드는지는 이전 저의 글을 보면 간단히 설정하실수 있습니다

https://hankyo-dev.tistory.com/entry/iOS%EC%97%90%EC%84%9C-uaal%EB%A1%9C-unity%EB%A5%BC-library%EB%A1%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

 

iOS에서 uaal로 unity를 library로 사용하기

iOS에서 3D 물리엔진등을 구현하기는 힘들다.3D 물리엔진은 유니티나 언리얼이 사용하야 구현이 쉬운데 이럴경우 ios native app이면서 3d 물리엔진이 필요한 경우에는 unity를 사용하는 방법이 있다UAA

hankyo-dev.tistory.com

 

 

1. iOS 에서 Unity3D로 데이터 보내기

iOS 프로젝트에서 유니티로 데이터를 보내는 방법은 간단합니다

먼저 유니티 프로젝트에 Text를 하나 추가하도록 하겠습니다

Canvas 게임오브젝트에 CanvasController 컴포넌트

 

Canvas GameObject에 Text를 추가했고 CanvasController 코드를 만들어 붙였습니다

using UnityEngine;
using TMPro;
using UnityEngine.UI;

public class CanvasController : MonoBehaviour
{
    [SerializeField] private TMP_Text canvasText;


    public void SetText(string txt)
    {
        canvasText.text = txt;
    }
}

 

다음으로 iOS Swift 프로젝트 입니다

struct UnityMessage
{
    let gameObjectName: String
    let functionName: String
    let message: String
}

class UnityManager: NSObject
{
    private var ufw: UnityFramework?
    ...
    
    func sendMessageToUnity(_ message: UnityMessage)
    {
        self.ufw?.sendMessageToGO(withName: message.gameObjectName,
                                  functionName: message.functionName,
                                  message: message.message)
    }
}

 

iOS에서 Unity에서 데이터를 보낼때는 간단하게 UnityFramework에 있는 'sendMessageToGO' API를 사용하면 됩니다

파라미터로는 첫번째는 실행할 함수가 있는 게임오브젝트 이름, 두번째는 실행함수 이름, 세번째는 함수안에 파라미터 값입니다

제가 만든 예시로 예를 들면 저는 Canvas 게임오브젝트에 붙어있는 CanvasController script의 SetText 함수를 호출하고자 하는거니 첫번째 파라미터에 Canvas, 두번째 파라미터에 SetText, 세번째 파라미터에는 내가 넣고싶은 값을 넣어주면 됩니다

 

2. Unity3D 에서 iOS로 데이터 보내기

Unity3D에서 iOS로 데이터를 보내는 방법은 첫번째 방법 보다는 조금 복잡합니다

우선 Objective-C++ 파일을 ios project에서 만들어 줍니다

Objective-C 생성

Objective-C++ 파일을 바로 만들수는 없어서 먼저 Objective-C 파일을 생성한 후 확장자가 .m 으로 되어 있을텐데 이를 .mm으로 바꿔줍니다

이러면 자동으로 Objective-C++로 바뀌게 됩니다

그리고 .h 인 header 파일도 만들어 줍니다

 

그리고 Objective-C 파일을 만들때 Briding Header를 만들겠냐는 팝업이 뜰텐데 Briding Header 파일을 만들어줍니다

Briding Header

이렇게 하면 .mm 파일, .h 파일, briding-header 파일 3가지가 만들어졌을텐데 파일들을 아래와 같이 세팅합니다

//  NativeCallProxy.h

#ifndef NativeCallProxy_h
#define NativeCallProxy_h

#import <Foundation/Foundation.h>

@protocol NativeCallsProtocol
@required
- (void) sendMessageToMobileApp:(NSString*)message;
// other methods
@end

__attribute__ ((visibility("default")))
@interface FrameworkLibAPI : NSObject
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>) aApi;

@end

#endif /* NativeCallProxy_h */

 

//  NativeCallProxy.mm

#import <Foundation/Foundation.h>
#import "NativeCallProxy.h"

@implementation FrameworkLibAPI

id<NativeCallsProtocol> api = NULL;
+(void) registerAPIforNativeCalls:(id<NativeCallsProtocol>)aApi
{
    api = aApi;
}

@end

extern "C"
{
    void sendMessageToMobileApp(const char* message)
    {
        return [api sendMessageToMobileApp:[NSString stringWithUTF8String:message]];
    }
}

 

// -Briding-Header

#import <UnityFramework/NativeCallProxy.h>

 

각각을 보면 우선 briding header 파일의 경우 swift와 objective-c++ 코드가 통신하기 위해 필요한 파일입니다

 

registerAPIforNativeCalls는 NativeProtocol을 등록하기 위한 함수입니다. swift 코드에 NativeProtocol을 상속시킬겁니다

그리고 NativeProtocol에 sendMessageToMobileApp을 구현한후 호출시킬겁니다

 

swift 코드를 보면 이해가 편합니다

class UnityManager: NSObject
{
	.....
    func launchUnity()
    {
        let isInitialized = self.ufw?.appController() != nil
        if isInitialized { self.ufw?.showUnityWindow() }
        else
        {
            ....
            // registerAPIforNativeCalls 함수를 호출해 등록
            NSClassFromString("FrameworkLibAPI")?.registerAPIforNativeCalls(self)
            ....
        }
    }
}

// NativeCallsProtocol을 상속받아 구현
extension UnityManager: NativeCallsProtocol
{
    func sendMessage(toMobileApp message: String!)
    {
        print(message)
    }
}

 

다음으로 Unity에 설정해 주어야 합니다

앞서 만든 .mm 파일과 .h 파일을 unity plugin 폴더에 넣어줍니다

통신하기 위한 C#코드를 하나 만들어 줍니다

using System.Runtime.InteropServices;

public class NativeAPI
{
#if UNITY_IOS
    [DllImport("__Internal")]
#endif
    public static extern void sendMessageToMobileApp(string message);
}

 

버튼이 눌러졌을때 해당 함수를 호출하는 코드를 하나 추가하도록 하겠습니다

public void OnSendMessageButtonClick()
{
    NativeAPI.sendMessageToMobileApp("유니티에서 왔다");
}

 

이 상태로 unity 프로젝트를 iOS Build 해줍니다

Build 후 Unity-iPhone>Libraries>Plugins 안에 넣어두었던 mm파일과 header 파일이 잘 들어가 있는것을 확인할 수 있습니다

header 파일은 Target Membership 접근을 Public으로 설정

그리고 바꿔주어야 하는게 있는데 Target Membership에 들어가면 default로 접근권한이 project로 되어있을 겁니다 이를 Public으로 바꿔주어야 합니다

이렇게 하면 끝입니다

Unity에서 iOS로 데이터가 잘 이동하는 것을 확인할 수 있습니다

 

Summarize