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
나중에 내가 보려요..

  


Related Posts:

  • [Unity] 주사위 굴려서 어떤 숫자가 나왔는지 판단하기.  https://hacchi-man.hatenablog.com/entry/2020/06/19/220000일본 사람인데, 정말 재치있게 해결했다. 머리가 좋은듯.일단 오브젝트에 하위 오브젝트를 붙여서 Y 축으로(하늘방향으로) 가장 높은 곳에 있는놈이 보이는 숫자다 라는건데, 단순하면서 재치있다. dice 오브젝트에 6개의 빈 오브젝트를 지정하고, dice에 연결된 스크립트에서는 각면에… Read More
  • [Unity] 요점만. Scene 관련 1.Scene에 보이는 대로 게임뷰 카메라를똑같이 보이고 싶다.   - GameObject -> AlignWIthView (https://qiita.com/atsushi33/items/6761a9cf8cbcb7e0e322)2.Git등에서 Scene의 변경사항을 추적할수 있도록 YML 형식으로 저장되게 옵션변경(또는 확인)  [Edit] => [Project Set… Read More
  • [Unity] 1300 자료./ 일본어 /알차다 http://tsubakit1.hateblo.jp/Unity… Read More
  • [Unity] ScriptableObject , 데이터를 깔끔하고 독립적으로 운영하는방법MonoBeheivour에 의존하지않으니 - 특정씬을 조회할 필요가 없다ㅏ-자동완성 도움받을수 있다.-에셋으로 등록할수 있다.-레퍼런스 추적가능? 하다.-느슨한결합-유니티오브젝트를 데이터형식으로 지정가능(Json이나Xml에서는 꿈도 못꾸지)란다.스크립트로 오브젝트를 만들어서 값들을 제어한다는  개념이다. 스테이지의 기본정보모음등은 json,xml등으로 만들어서 세팅하기도 하는데,이를… Read More
  • [Unity] GC Alloc를 발생시키지 않는 C# 코딩 https://qiita.com/sapphire_al2o3/items/4f517523f50e0113af1fUnity 코드를 쓸 때 GC Alloc가 발생하는 패턴을 조사했다. GC Alloc이 줄어들 패턴 good했지만, 코드가 알기 어려울 경우도 있으므로 반드시 개서를 할 필요는 없다.Unity 2018.4에서 동작 확인문자와 숫자의 연결badint i = 123 ; st… Read More

0 comments:

댓글 쓰기