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

製作 Unity Plugin for iOS

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for Johnny Sung Johnny Sung
September 11, 2014

製作 Unity Plugin for iOS

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

Avatar for Johnny Sung

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