39
製作 Unity Plugin for iOS Johnny Sung 2014.09.11 @ CocoaHeads Taipei

製作 Unity Plugin for iOS

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: 製作 Unity Plugin for iOS

製作 Unity Plugin for iOSJohnny Sung

2014.09.11 @ CocoaHeads Taipei

Page 2: 製作 Unity Plugin for iOS

https://fb.com/j796160836

Johnny SungMobile devices Developer

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

http://about.me/j796160836

Page 3: 製作 Unity Plugin for iOS

我是不是來錯場合了?

這裡是CocoaHeads...

Page 4: 製作 Unity Plugin for iOS

Unity的概念

• GameObject

• Component

Page 5: 製作 Unity Plugin for iOS

GameObject

GameObject

Page 6: 製作 Unity Plugin for iOS

GameObject

Component

Page 7: 製作 Unity Plugin for iOS

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

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

Page 8: 製作 Unity Plugin for iOS

MonoBehaviour 的⽣生命週期

• Awake() 創造時初始化

• Start() 執⾏行時初始化

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

• FixedUpdate() 物理迴圈

Page 9: 製作 Unity Plugin for iOS
Page 10: 製作 Unity Plugin for iOS

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

Page 11: 製作 Unity Plugin for iOS

說好的 iOS Plugin 呢?

Page 12: 製作 Unity Plugin for iOS

Unity Plugin 的呼叫⽅方式

C# (呼叫的接⼝口)

C(⾃自定義的接⼝口)

Objective-C

Objective-CUnitySendMessage()

C#(對應的接⼝口)

(Unity Engine) (Native)

Page 13: 製作 Unity Plugin for iOS

!#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 !

Page 14: 製作 Unity Plugin for iOS

!@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 ( ˊ_>ˋ )

Page 15: 製作 Unity Plugin for iOS

⾃自訂 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

Page 16: 製作 Unity Plugin for iOS

跟Unity相連接!

Page 17: 製作 Unity Plugin for iOS

!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#對應的接⼝口

Page 18: 製作 Unity Plugin for iOS

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

SampleMyView.cs

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

建⽴立⼀一個GameObject

增加⼀一個MyViewObject這個Component

Page 19: 製作 Unity Plugin for iOS

從 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

Page 20: 製作 Unity Plugin for iOS

從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 宣告

Page 21: 製作 Unity Plugin for iOS

從Obj-C 回傳 Unity 資料

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

GameObject Name Method Name Parameter

Page 22: 製作 Unity Plugin for iOS

打包執⾏行

Page 23: 製作 Unity Plugin for iOS

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

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

• Assets/Plugins/iOS

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

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

Page 24: 製作 Unity Plugin for iOS
Page 25: 製作 Unity Plugin for iOS
Page 26: 製作 Unity Plugin for iOS

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

• 加⼊入所需的Framework

• 調整Complier Flags ( -fobjc-arc )

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

• xcode專案編譯

Page 27: 製作 Unity Plugin for iOS

調整Complier Flags

Page 28: 製作 Unity Plugin for iOS

放上 Asset Store 賺外快!

Page 29: 製作 Unity Plugin for iOS

Demo Project

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

Page 30: 製作 Unity Plugin for iOS

Q & A

Page 31: 製作 Unity Plugin for iOS

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/

Page 32: 製作 Unity Plugin for iOS

Thanks !

Page 33: 製作 Unity Plugin for iOS

補充:Unity 畫⾯面的按鈕

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

Page 34: 製作 Unity Plugin for iOS

補充: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

Page 35: 製作 Unity Plugin for iOS

補充:有關const char *

const char * const myString;

指標所指向的記憶體位置

指向記憶體位置的內容

Page 36: 製作 Unity Plugin for iOS

補充:有關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

Page 37: 製作 Unity Plugin for iOS

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

Page 38: 製作 Unity Plugin for iOS

補充: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

Page 39: 製作 Unity Plugin for iOS

Unity 應⽤用領域

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

想做遊戲?