Upgrade to Pro — share decks privately, control downloads, hide ads and more …

製作 Unity Plugin for iOS

Johnny Sung
September 11, 2014

製作 Unity Plugin for iOS

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

Johnny Sung

September 11, 2014
Tweet

More Decks by Johnny Sung

Other Decks in Programming

Transcript

  1. ⼀一個空⽩白的 Component ⻑⾧長這樣 using UnityEngine;
 using System.Collections;
 
 public class

    testComponent : MonoBehaviour {
 
 // Use this for initialization
 void Start () {
 
 }
 
 // Update is called once per frame
 void Update () {
 
 }
 }
  2. MonoBehaviour 的⽣生命週期 • Awake() 創造時初始化 • Start() 執⾏行時初始化 • Update()

    繪圖迴圈 (依效能⽽而定,例60fps) • FixedUpdate() 物理迴圈
  3. ! #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 !
  4. ! @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 ( ˊ_>ˋ )
  5. ⾃自訂 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
  6. ! 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#對應的接⼝口
  7. ! public class SampleMyView : MonoBehaviour
 {
 MyViewObject myViewObject;
 


    void Start()
 {
 myViewObject =
 (new GameObject("MyViewObject")).AddComponent<MyViewObject>();
 myViewObject.Init();
 }
 } SampleMyView.cs 配合⽣生命週期 並使⽤用之 建⽴立⼀一個GameObject 增加⼀一個MyViewObject這個Component
  8. 從 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
  9. 從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 宣告
  10. 打包Obj-C進Unity (2/2) • 加⼊入所需的Framework • 調整Complier Flags ( -fobjc-arc )

    • 依需求調整所需的設定 • Framework Search Paths • Other Linker Flags • Info-plist • xcode專案編譯
  11. 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/
  12. 補充:Unity 畫⾯面的按鈕 public class buttonUI : MonoBehaviour {
 
 void

    OnGUI ()
 {
 if (GUI.Button (new Rect (20, 10, 100, 40), "ButtonText")) {
 Debug.Log("Clicked!");
 }
 }
 }
  13. 補充: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
  14. 補充:有關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
  15. 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.html http://stackoverflow.com/questions/1304176/objective-c-difference-between-id-and-void
  16. 補充: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