Unity3D iOS Plugin 만들어 연동하기

 유니티3D 안드로이드 플러그인을 유니티3D가 메인이 되는 플러그인이클립스가 메인이 되는 플러그인 2가지를 만들어 봤었습니다. 이번에는 iOS 플러그인을 만들어 연동해 보겠습니다.


1. 유니티3D 프로젝트 생성

 유니티3D 프로젝트를 생성 후 iOSManager, TestGUI 컴포넌트를 만들었습니다. 안드로이드와 마찬가지로 Plugins/iOS 폴더를 만들어줍니다. 소스를 보기전에 툴에서 실행했을 때 화면은 위와같습니다. 툴에서는 버튼을 클릭해봐야 작동하지 않습니다. 안드로이드든 iOS든 플러그인 연동은 디바이스에서만 작동을하죠.


2. 유니티3D에서 iOS 플러그인과 통신

using UnityEngine;

//using for DllImport
using System.Runtime.InteropServices;

public class iOSManager : MonoBehaviour 
{
static iOSManager _instance;
public static string strLog = "WestWoodForever's Unity3D iOS Plugin Sample";
//private AndroidJavaObject curActivity;
[DllImport("__Internal")]
private static extern void iOSPluginHelloWorld(string strMessage);
public static iOSManager GetInstance()
{
if( _instance == null )
{
_instance = new GameObject("iOSManager").AddComponent<iOSManager>();
}
return _instance;
}
void Awake()
{
/*
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
curActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");
*/
}
public void CalliOSFunc(string strMessage)
{
//curActivity.Call("AndroidFunc", strMsg);
Debug.Log("UnityLog1");
iOSPluginHelloWorld(strMessage);
Debug.Log("UnityLog2");
}
public void SetLog(string _strLog)
{
Debug.Log("Set UnityLog");
strLog = _strLog;
}

}

 먼저 iOSManager 컴포넌트입니다. 주석처리한 부분은 기존에 안드로이드 플러그인 부분입니다. 비교가 될 듯해서 주석으로 남겨봤습니다. 정적으로 실행파일에 연결되어 있는 플러그인을 임포트하기 위해 [DllImport("__Internal")] 이 사용되었고 플러그인에 있는 함수를 extern으로 선언하고 바로 함수 호출하듯이 호출하고 있습니다. 안드로이드에 비해 크게 어려울 것은 없고 오히려 더 쉬워보입니다.

Assets/iOSManager.cs(12,10): error CS0246: The type or namespace name `DllImport' could not be found. Are you missing a using directive or an assembly reference?
Assets/iOSManager.cs(12,10): error CS0246: The type or namespace name `DllImportAttribute' could not be found. Are you missing a using directive or an assembly reference?
Assets/iOSManager.cs(12,10): error CS0246: The type or namespace name `DllImportAttribute' could not be found. Are you missing a using directive or an assembly reference?

 DllImport를 사용하기 위해 using System.Runtime.InteropServices를 해줬습니다. 해주지 않으면 위와 같은 오류가 발생합니다.

 void OnGUI()
 {
  float fYpos = 0;
  GUI.Label(new Rect(0, fYpos, 400, 50), iOSManager.strLog);
  
  fYpos += 50;
  if (GUI.Button (new Rect(0, fYpos, 100, 50), "Call iOS") == true)
  {
   iOSManager.GetInstance().CalliOSFunc("Unity3D iOS Plugin Test Ok");
  }
 }

 TestGUI 컴포넌트의 OnGUI 입니다.


3. iOS Native Plugin mm 파일 작성

 iOS 네이티브와 통신하기 위한 오브젝트C 소스 파일을 만듭니다. 파일명은 원하시는 걸로 하면 됩니다.

//
//  NativeiOSPlugin.mm
//  Unity-iPhone
//
//  Created by wwforeverMAC on 13. 8. 27..
//
//
/*
#import "NativeiOSPlugin.h"

@implementation NativeiOSPlugin

@end
*/
extern "C"
{
void iOSPluginHelloWorld(const char* strMessage)
{
    NSLog(@"iOS Log 1");
    UnitySendMessage("iOSManager", "SetLog", strMessage);
    NSLog(@"iOS Log 2");
}
}
 extern "C" 안에 있는 iOSPluginHelloWorld 함수가 유니티3D C#에서 호출하는 함수입니다. 유니티3D 에서는 선언할 때 인자로 string으로 했는데 실제로 플러그인쪽에 구현할 때는 const char* 로 해야합니다.

 mm 파일로 했기 때문에 extern "C" {}로 감싸주었는데 m 파일로 iOS 플러그인 파일을 만드신다면 extern으로 감싸주지 않아도 됩니다.

 파일을 저장 후 Plugins/iOS 폴더에 복사 또는 이동 시킵니다. 다음부터는 해당 폴더에서 직접 수정 작업을 하면 됩니다. 또한 같이 생성된 h 파일은 아직 샘플 수준이라 불필요하므로 삭제 합니다. 사실 h 파일은 있어도 나중에 xcode 프로젝트의 프로젝트 네비게이터에 추가되진 않습니다.


4. 유니티3D 빌드

 SDK Version을 Device SDK로 한 후 빌드 해줍니다.

 전 iOSBuildProject 로 빌드 했습니다.

 xcode 프로젝트가 생성되었습니다.


5. Xcode 프로젝트 빌드 및 실행


 생성된 프로젝트를 열어보면 유니티3D의 플러그인 폴더에 넣어두었던 소스 파일이 그림과 같이 프로젝트 네비게이터에 추가되어 있는 것을 확인할 수 있습니다. 추후 수정작업은 xcode에 자동 추가된 파일에 하지 마시고 기존에 유니티3D 플러그인 폴더에 있는 것을 수정해주셔야 합니다. 나중에 빌드될 때 플러그인 폴더의 것이 복사가 되기 때문이죠.

 빌드하고 실행해서 버튼을 눌러보면 위와 같이 실행 된 것을 볼 수 있습니다.

 Plugins/iOS에 넣는 플러그인 파일로 넣는대신 그림과 같이 빌드된 iOS xcode 프로젝트의 Classes/RegisterClasses.cpp 에 작업을 해도 무방합니다. 대신 cpp니까 오브젝트C 문법은 사용하면 안되겠죠.

 마지막으로 한참 소스를 수정하시고 다시 빌드 시 위와 같이 나온다면 꼭 Append를 눌러 병합하는게 더 안전한 것 같습니다.

 비교적 안드로이드 플러그인 보다는 이슈도 적고 작업도 쉬운 것 같습니다. cocos2d-x에 유니티3D에서 말하는 플러그인과 비슷했던 프레임워크 작업할 때는 iOS용 static lib로 만들기도 했었는데 유니티3D도 iOS 플러그인을 이런 소스 작업방식 말고 lib 형태로도 나중에 만들어 봐야겠네요.

이 블로그의 인기 게시물

Unity3D Prime31 처럼 자신만의 안드로이드 플러그인을 만들어보자

CMake Windows에 설치하기