製作 Unity Plugin for iOS

Preview:

DESCRIPTION

製作 Unity Plugin for iOS 從Unity的基本概念帶到iOS的Plugins實作 2014.09.11 @ CocoaHeads Taipei

Citation preview

製作 Unity Plugin for iOSJohnny Sung

2014.09.11 @ CocoaHeads Taipei

https://fb.com/j796160836

Johnny SungMobile devices Developer

https://plus.google.com/+JohnnySung

http://about.me/j796160836

我是不是來錯場合了?

這裡是CocoaHeads...

Unity的概念

• GameObject

• Component

GameObject

GameObject

GameObject

Component

⼀一個空⽩白的 Component ⻑⾧長這樣

using UnityEngine;using System.Collections;public class testComponent : MonoBehaviour {     // Use this for initialization    void Start () {        }        // Update is called once per frame    void Update () {        }}

MonoBehaviour 的⽣生命週期

• Awake() 創造時初始化

• Start() 執⾏行時初始化

• Update() 繪圖迴圈 (依效能⽽而定,例60fps)

• FixedUpdate() 物理迴圈

http://docs.unity3d.com/ScriptReference/

說好的 iOS Plugin 呢?

Unity Plugin 的呼叫⽅方式

C# (呼叫的接⼝口)

C(⾃自定義的接⼝口)

Objective-C

Objective-CUnitySendMessage()

C#(對應的接⼝口)

(Unity Engine) (Native)

!#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> !extern UIViewController* UnityGetGLViewController(); extern "C" void UnitySendMessage(const char*, const char*, const char*); !@interface MyViewPlugin : NSObject @property (nonatomic, strong) UIView* myView; @property (nonatomic, strong) NSString* gameObjectName; @end

MyViewPlugin.mm

Get Started !

!@implementation MyViewPlugin !- (id)initWithGameObjectName:(const char*)gameObjectName_ { self = [super init]; UIView* view = UnityGetGLViewController().view; self.myView = [[UIView alloc] initWithFrame:view.frame]; self.myView.backgroundColor = [UIColor blueColor]; [view addSubview:self.myView]; self.gameObjectName = [NSString stringWithUTF8String:gameObjectName_]; return self; } !- (void)dealloc { [self.myView removeFromSuperview]; } !@end !!

MyViewPlugin.mm就只是⼀一個藍⾊色的View ( ˊ_>ˋ )

⾃自訂 C語⾔言 接⼝口!extern "C" { void* _MyViewPlugin_Init(const char* gameObjectName); void _MyViewPlugin_Destroy(void* instance); } !void* _MyViewPlugin_Init(const char* gameObjectName) { id instance = [[MyViewPlugin alloc] initWithGameObjectName:gameObjectName]; return (__bridge void*)instance; } !void _MyViewPlugin_Destroy(void* instance) { MyViewPlugin* myViewPlugin = (__bridge MyViewPlugin*)instance; myViewPlugin = nil; }

MyViewPlugin.mm

跟Unity相連接!

!public class MyViewObject : MonoBehaviour{     IntPtr myView;#if UNITY_IPHONE    [DllImport("__Internal")]    private static extern IntPtr _MyViewPlugin_Init(string gameObject);    [DllImport("__Internal")]    private static extern int _MyViewPlugin_Destroy(IntPtr instance);#endif        public void Init()    {#if UNITY_IPHONE        myView = _MyViewPlugin_Init(name);#endif    }    void OnDestroy()    {#if UNITY_IPHONE        if (myView == IntPtr.Zero)            return;         _MyViewPlugin_Destroy(myView);#endif    }}

MyViewObject.cs

C#對應的接⼝口

!public class SampleMyView : MonoBehaviour{     MyViewObject myViewObject;        void Start()    {        myViewObject =            (new GameObject("MyViewObject")).AddComponent<MyViewObject>();        myViewObject.Init();    }}

SampleMyView.cs

配合⽣生命週期 並使⽤用之

建⽴立⼀一個GameObject

增加⼀一個MyViewObject這個Component

從 Unity 呼叫 Obj-C ⽅方法

C# 傳送

Objective-C 接收MyViewObject.cs

MyViewPlugin.mm

C 宣告

![DllImport("__Internal")] private static extern int _MyViewPlugin_Destroy(IntPtr instance);

extern "C" { void _MyViewPlugin_Destroy(void* instance); }

C# 宣告

_MyViewPlugin_Destroy(myView);

void _MyViewPlugin_Destroy(void* instance) { !}

MyViewObject.cs

MyViewPlugin.mm

從Obj-C 回傳 Unity 資料

UnitySendMessage([self.gameObjectName UTF8String], "CallFromObjC", [@"Hello" UTF8String]);

public void CallFromObjC(string message){    Debug.Log (message);}

C# 接收

Objective-C 傳送

extern "C" void UnitySendMessage(const char*, const char*, const char*);

MyViewObject.cs

MyViewPlugin.mm

C 宣告

從Obj-C 回傳 Unity 資料

UnitySendMessage(const char*, const char*, const char*);

GameObject Name Method Name Parameter

打包執⾏行

打包Obj-C進Unity (1/2)

• 路徑設定 (需⾃自⾏行開⽴立資料夾)

• Assets/Plugins/iOS

• 放⼊入Obj-C的程式碼 • .mm • .a

• Unity編譯! (產⽣生xcode專案)

打包Obj-C進Unity (2/2)

• 加⼊入所需的Framework

• 調整Complier Flags ( -fobjc-arc )

• 依需求調整所需的設定 • Framework Search Paths • Other Linker Flags • Info-plist

• xcode專案編譯

調整Complier Flags

放上 Asset Store 賺外快!

Demo Project

https://github.com/j796160836/Unity-iOSPlugins

Q & A

Great References• Unity Webview

• https://github.com/gree/unity-webview • Building Plugins for iOS

• http://docs.unity3d.com/Manual/PluginsForIOS.html • Plugins (Pro/Mobile-Only Feature)

• http://docs.unity3d.com/Manual/Plugins.html • 懂點Unity Plugin,替荷包省點錢!(iOS篇)

• http://www.unityin.com/2013/05/%E6%87%82%E9%BB%9Eunity-plugin%EF%BC%8C%E6%9B%BF%E8%8D%B7%E5%8C%85%E7%9C%81%E9%BB%9E%E9%8C%A2%EF%BC%81ios%E7%AF%87/

Thanks !

補充:Unity 畫⾯面的按鈕

public class buttonUI : MonoBehaviour {    void OnGUI ()    {        if (GUI.Button (new Rect (20, 10, 100, 40), "ButtonText")) {            Debug.Log("Clicked!");         }    }}

補充:MonoBehaviour 的⽣生命週期

• Awake():⽤用於在游戲開始之前初始化變量或游戲狀態,在程式整個⽣生命周期內僅被執⾏行⼀一次。Awake在所有GameObject初始化之後執⾏行,因此可以在⽅方法中安全地與GameObject進⾏行通信。

• Start():僅在所有程式的Update⽅方法第⼀一次被呼叫前執⾏行,且僅在程式實例被啟⽤用時執⾏行。Start在所有程式的Awake⽅方法全部執⾏行完成後才執⾏行。

• Update():在每次渲染新的⼀一個Frame時執⾏行。由於該⽅方法呼叫的頻率與設備性能、被渲染對象有關,導致同⼀一游戲在不同機器的效果不⼀一致(因為Update⽅方法的執⾏行時間間隔不⼀一致)。

• FixedUpdate():在固定的時間間隔執⾏行,不受游戲幀率(FPS)的影響。所以處理RigidBody時最好⽤用FixedUpdate。FixedUpdate的時間間隔可在⼯工程設置中更改(Edit --> Project Setting --> Time)。

• LateUpdate():所有程式的Update⽅方法呼叫後執⾏行。例如相機跟隨即是在LateUpdate⽅方法中實現。

• OnGUI():在渲染和處理GUI事件時執⾏行。

• Reset():⽤用⼾戶點擊屬性監視⾯面板(Inspector)的Reset按鈕或⾸首次添加該組件時執⾏行,僅在編輯模式下執⾏行。

• OnDestroy():當GameObject將被銷毀時執⾏行。

http://www.cnblogs.com/lunarfire/p/3494716.html

補充:有關const char *

const char * const myString;

指標所指向的記憶體位置

指向記憶體位置的內容

補充:有關const char *• char * myString;

• 都可以改

• const char * myString; ( 或 char const * myString; )

• 字串內容不能動,但指向的位址可以改

• char * const myString;

• 指的位址不能動,但是位址裡的字串可以改

• const char * const myString;

• 都不能改

http://www.programmer-club.com.tw/ShowSameTitleN/c/37760.html

void * 與 id

• void * • a reference to some random chunk o' memory with untyped/

unknown contents

• ⼀一個任意指標,可⽤用來指向任何型別或內容的記憶體區塊

• id • a reference to some random Objective-C object of unknown

class

• ⼀一個任意指標,可以指向 Obj-C 中的物件

http://justlink-linus.blogspot.tw/2012/11/id-void-void-pointer.htmlhttp://stackoverflow.com/questions/1304176/objective-c-difference-between-id-and-void

補充:Assets資料夾保留字

• Standard Assets • Editor • Plugins

• Plugins/x86 • Plugins/Android • Plugins/iOS

• Resources

http://wiki.unity3d.com/index.php/Special_Folder_Names_in_your_Assets_Folder

Unity 應⽤用領域

https://www.facebook.com/groups/581769871867384

想做遊戲?

Recommended