2021년 1월 19일 화요일

Unity3d 에서 네이티브 IOS 코드 불러내서 사용하기-심플

 참고사이트:https://twnkls.com/en/blogs/howto-native-android-plugins-for-unity3d-2/

한번보면 알게되는 강좌 :https://www.youtube.com/watch?v=zP5mjHzJR-o (Creating an iOS Plugin for Unity3D)


1.일단 유니티 프로젝트를 생성한다.

2.Assets 목록에 
- Plugins
  -- iOS
- Scripts 
가 있는지 확인하고 없으면 생성한다.

3. IOS폴더에 "ItsYourPlugin"이라는 스크립트를 생성하자.
이 스크립트는 생성하면 cs이지만, IOS연동용으로 하기위해  .mm 확장자로 바꿔야 한다.

4.바꿨다면 아이콘이 퍼즐조각으로 바뀐다. ( 난 유툽강좌대로 MyPlugin으로 했다)


5.이제 저걸 더블클릭하면 Xcode가 에디터에 저 파일의 내용이 뜬다. cs 용 내용이므로 이걸 다 지우고 아래처럼 object-c코드로 바꾼다.
이 파일에는 헤더(보통 .h파일)와 바디(보통 .m)파일의 내용을 구분없이 한 파일에 쓰도록 한다.
ItsYourPlugin는 기본적으로 다음과 같이 구성한다.

#import <Foundation/Foundation.h>


// 머리,xcode에서 .h 라고 있던녀석들
@interface MyPlugin: NSObject
{
}
@end

// 몸통,xcode에서 .m 라고 있던녀석들
@implementation MyPlugin

@end

// 꼬리,Unity에서 보여줄 녀석들
extern "C"
{

}


6. object-c 클래스를 unity 에서 불러내서 연동하려면 (객체화) 라는 것을 유니티가 할텐데,  유니티가 object-c쪽의 함수를 호출(정확히는 extern c를 통해 호출) 할때 마다 객체를 생성하면 메모리가 미쳐나갈수 있으니 싱글톤으로 만들어지도록 object-c쪽에 코드를 넣어야한다. 
(게임 루프는 1초에 30-60 번! 이나 호출하기때문이다!!)

// 몸통,xcode에서 .m 라고 있던녀석들
@implementation MyPlugin

+(MyPlugin*) sharedInstance       //현재객체(MyPlugin)을 돌려받는 싱글톤 함수 선언
{

static
MyPlugin *_sharedInstance; //스택틱 빈객체선언
static dispatch_once_t onceToken; //APP 라이프 사이클에 마추어 단 한번만 실행되로록 보장 이라네.. dispatch_once(&onceToken, ^{ NSLog(@"Create Instance IOS"); _sharedInstance = [[MyPlugin alloc] init]; }); // obejct-c 의 싱글톤 패턴작성패턴이다. 토큰이 없으면 MyPlugin 객체생성 후 스택틱 변수에넣음 return _sharedInstance; //스택틱 변수를 돌려줌.잉? 그럼왜 _s } @end


7.자, 이제 유툽강좌에 있던 내용대로 써보자

#import <Foundation/Foundation.h>

@interface MyPlugin: NSObject
{

    NSDate *creationDate;
}
@end

@implementation MyPlugin

+(MyPlugin*) sharedInstance
{
    static MyPlugin *_sharedInstance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"Create Instance IOS");
        _sharedInstance = [[MyPlugin alloc] init];
    });
    
    return _sharedInstance;
}


-(id)init
{
    self = [super init];
    if (self)
        [self initHelper];
    return self;
    
}

-(void)initHelper
{
    NSLog(@"InintHelper callsed");
    creationDate = [NSDate date];
}

-(double)getElapsedTime
{   
    // 클래스 초기화 때 실행하는 initHelper 에서 creationDate(시작시간이겠지)을 만들고, timeIntervalSinceDate로 실행시간을 구한다. 
    return [[NSDate date] timeIntervalSinceDate:creationDate];
}
@end


extern "C"
{
double IOSgetElapsedTime() { //유니티에서는 이 함수를 호출할것이다.싱글톤객체 얻은후 getElapseTime 반환값을 유니티쪽에 던져줌.
    return [[MyPlugin sharedInstance] getElapsedTime];
}
}

8.일단 object-c쪽은 준비가 되었다. 이제 Unity의 스크립트 등에서 object-c에서 만들어둔 함수 IOSgetElapsedTime 를 불러내보자.
Assets의 Scripts폴더밑에 PluginTest라는 스크립트를 생성하고 아래처럼 넣자

using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;

public class PluginTest : MonoBehaviour
{
#if UNITY_IOS
	[DllImport("__Internal")] 
    //DllImport는 C#에서 다른 프로그램을 불러낼때 쓰인다
    private static extern double IOSgetElapsedTime(); //아까 object-c에서 만든함수랑 같은 이름을 지정한다.
#endif
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Elapsed" + getElapsedTime());
    }

    int frameCounter = 0;
    // Update is called once per frame
    void Update()
    {
        frameCounter++;
        if (frameCounter >= 5) {
        	Debug.Log("Tick" + getElapsedTime());
        	frameCounter = 0;
        }
    }

    double getElapsedTime() { //Start랑 Update에서 불리는 함수다. IOS일때만 불리도록 했다.
    	if (Application.platform == RuntimePlatform.IPhonePlayer) 
    	   return IOSgetElapsedTime();
    	return 0;
    }
}

9.자 이 스크립트를 카메라에 붙이자. 카메라는 항상있으니까.. 그럼 씬이 시작될때 start->update->update->update..... 하면서 실행후 지난시간들이 Log에 찍힌다.

10.이제   유니티 프로젝트를 빌드해 보자


10.빌드하면 Unity를 Xcode에서 빌드할수 있도록 저장폴더를 물어보고, 폴더를 선택했다면, Xcode가 열리면서 현재작업중인 모든 유티니관련 자료,라이브러리가 포함된 프로젝트가 열린다.

11.위에서 작성한(ItsYourPlugin.mm)의 내용이 바뀌거나, unity에서 관련스크립트가 변경되었다면 항상 command+b를 눌러서 과정10에서 생성된 프로젝트에 동일하게 반영되도록 해야한다.



Github : https://github.com/sugoigroup/cuddly-spork.git
나중에 내가 보려요..

  


0 comments:

댓글 쓰기