7、iOS、Androidとのインタラクションプレミアム編

7764 ワード

本文は「UnityとiOS、Androidプラットフォームの統合」シリーズの文章の一つに属し、転載は出典を明記してください.UnityとiOS、Androidのインタラクションを優雅に実現する方法について説明します.
ゼロ、はじめに
市販されているSDKは基本的にオリジナルiOS、Androidであり、Unityアクセスの過程で、簡単に呼び出すのではなく、オリジナルAPIアクセスのセットであり、これらの問題を処理するために完全な解決策が必要であることが多い.ここで、自分の案を提出して、レンガを投げて玉を引くことを意味して、もしみんなが他の考えがあれば、伝言の交流を望んでいます.この解決策は基礎原理の拡張である.4、iOS、Androidとのインタラクティブ理論編5、iOS、Androidとのインタラクティブ実践編——アクティブコール6、iOS、Androidとのインタラクティブ実践編——伝達パラメータ
一、需要分析
実際のプロジェクトの使用では、
  • C#コードを使用して関連機能
  • を呼び出す.
  • 呼び出し時に特定のプラットフォーム
  • を区別する必要はない.
  • エディタモードでのシミュレーションテスト
  • 複雑なタイプのパラメータ相互伝達
  • を実現する.
  • リスニング
  • を実現
  • コールバック
  • を実現
  • ……

  • 二、方案設計
    <<
  • C#コードを使用して関連機能
  • を呼び出す.
    >>シナリオ:
    コードを職責に従って階層化するには、次の手順に従います.
  • 上層論理(C#)
  • 上位論理呼び出し用インタフェース(C#)
  • SDKを呼び出すインタフェース(C+、Java)
  • SDK API(OC、Java)

  • <<
  • 呼び出し時に特定のプラットフォーム
  • を区別する必要はない.
  • エディタモードでのシミュレーションテスト
  • >>シナリオ:
    前の需要シナリオを拡張するには、次の手順に従います.
  • 上層論理呼び出し用インタフェース(C#)は、コンパイルスイッチを使用して関数内部でプラットフォームに基づいて
  • を呼び出す.
        public void Login()
        {
            Login_();
        }
        #if UNITY_EDITOR
        private static void Login_()
        {
            Debug.Log("SDK Login");
        }
        #elif UNITY_IOS
        [DllImport("__Internal")]private static extern void Login_();
        #elif UNITY_ANDROID
    private static void Login_() 
    {
        using (AndroidJavaClass jc = new AndroidJavaClass("xxx.xxx.xxx))
        {
            jc.CallStatic("Login_"); 
        }
    }
        #endif
    

    <<
  • 複雑なタイプのパラメータ相互伝達
  • を実現する.
    >>シナリオ:
  • Jsonシーケンス化、逆シーケンス化相関タイプ
  • を用いる.
  • 相互伝達JSON文字列
  • public class Message
    {
        public int id;
        public string name;
        public static string ToJson(Message msg)
        {
            return Json.Serialize(msg);
        }
        public static Message FromJson(string json)
        {
            return Json.DeSerialize(json);
        }
    }
    public void SetLoginInfo(Message msg)
    {
        SetLoginInfo_(Message.ToJson(msg));
    }
    #if UNITY_EDITOR
    private static void SetLoginInfo_(string msg)
    {
        Debug.Log("SDK SetLoginInfo" + msg);
    }
    #elif UNITY_IOS
    [DllImport("__Internal")]private static extern void SetLoginInfo_(string msg);
    #elif UNITY_ANDROID
    private static void SetLoginInfo_()
    {
        using (AndroidJavaClass jc = new AndroidJavaClass("xxx.xxx.xxx))
        {
            jc.CallStatic("SetLoginInfo_", msg); 
        }
    }
    #endif
    public Message GetLoginInfo()
    {
        Message.FromJson(GetLoginInfo_());
    }
    #if UNITY_EDITOR
    private static string GetLoginInfo_()
    {
        return "{\"id\":1,\"name\":\"abc\"}";
    }
    #elif UNITY_IOS
    [DllImport("__Internal")]private static extern string GetLoginInfo_();
    #elif UNITY_ANDROID
    private static string GetLoginInfo_()
    {
        using (AndroidJavaClass jc = new AndroidJavaClass("xxx.xxx.xxx))
        {
            return jc.CallStatic("GetLoginInfo_"); 
        }
    }
    #endif
    

    <<
  • リスニング
  • を実現
    >>シナリオ:
  • 上層論理呼び出し用インタフェース(C#)、傍受
  • を提供する
  • SDKのインタフェース(C++、Java)を呼び出し、オリジナルAPIのリスニング
  • を登録する
  • UnitySendMessageを使用して指定C#メソッドを呼び出し、C#レイヤのリスニング
  • をトリガーする.
  • 唯一のGameObjectを使用して、UnitySendMessageが上位論理呼び出しのために受信するインタフェース(C#)
  • を担当する.
    public class XXXSDKEventHandler : Monobehaviour
    {
        public event Action onLogin;
        public void OnLogin()
        {
            if(onLogin != null)
            {
                onLogin();
            }
        }
    }
    public class XXXSDKManager
    {
        private XXXSDKEventHandler handler;
        public XXXSDKManager()
        {
            handler = new GameObject("XXXSDKEventHandler").AddComponent();
            Object.DontDestroyOnLoad(handler.gameObject);
        }
        public event Action onLogin
        {
            add { handler.onLogin += value; }
            remove { handler.onLogin -= value; }
        }
    }
    

    SDKを呼び出すインタフェース(C++)
    void OnLogin(){
        UnitySendMessage("XXXSDKEventHandler", "OnLogin", "");
    }
    

    SDKを呼び出すインタフェース(Java)
    void OnLogin(){
        UnityPlayer.UnitySendMessage("XXXSDKEventHandler", "OnLogin", "");
    }
    

    <<
  • コールバック
  • を実現
    >>シナリオ:
  • 上層論理呼び出し用インタフェース(C#)は、コールバックID
  • をキャッシュして割り当てる.
  • SDKのインタフェース(C++、Java)を呼び出し、コールバックID
  • を受信する
  • UnitySendMessageを使用して指定C#メソッドを呼び出し、C#レイヤのコールバック
  • をトリガする.
  • UnitySendMessage
  • を受信するために一意のGameObjectを使用する
    public class XXXSDKEventHandler : Monobehaviour
    {
        private int cba_key = 0;
        private Dictionary cbas = new Dictionary();
        public int AddCallbackAction(Action action)
        {
            cbas.Add(cba_key, action);
            return cba_key++;
        }
        private void Receiver(string jsonMessage)
        {
            JsonObject jo = Json.DeserializeObject(jsonMessage);
            int key = int.Parse(jo["cba_key"].ToString());
            if (!cbas.ContainsKey(key)) { return; }
            Action action = cbas[key];
            if (action != null) { action(result); }
            cbas.Remove(key);
        }
        #region     
        Queue callbackQueue = new Queue();
        private void MessageHandle(string json)
        {
            JsonObject jo = Json.DeserializeObject(json);
            string funcName = jo["funcName"].ToString();
            string message = jo["message"].ToString();
            this.callbackQueue.Enqueue(funcName);
            this.callbackQueue.Enqueue(message);
        }
        void Update()
        {
            while (true)
            {
                yield return null;
                while (callbackQueue.Count >= 2)
                {
                    SendMessage(this.callbackQueue.Dequeue(), this.callbackQueue.Dequeue());
                }
            }
        }
        #endregion
    }
    public class XXXSDKManager
    {
        private XXXSDKEventHandler handler;
        public XXXSDKManager()
        {
            handler = new GameObject("XXXSDKEventHandler").AddComponent();
            Object.DontDestroyOnLoad(handler.gameObject);
        }
        public Login(Action onFinish)
        {
            Login_(handle.AddCallbackAction(onFinish));
        }
        #if UNITY_EDITOR
        private static void Login_(int callbackID)
        {
            Debug.Log("SDK Login");
            handler.SendMessage("Receiver","{\"funcName\":\"Receiver\",\"message\":\"{\\\"cba_key\\\":\\\"" + callbackID + "\\\"}\"}");
        }
        #elif UNITY_IOS
        [DllImport("__Internal")]private static extern void Login_(int callbackID);
        #elif UNITY_ANDROID
        private static void Login_(int callbackID) 
        {
            using (AndroidJavaClass jc = new AndroidJavaClass("xxx.xxx.xxx))
            {
                jc.CallStatic("Login_", callbackID); 
            }
        }
    }
    

    SDKのコールバックインタフェース(C++)
    void Login_(int callbackID){
        //  xxx,      
        UnitySendMessage("XXXSDKEventHandler", "OnLogin", [NSString stringWithFormat:@"{\"funcName\":\"Receiver\",\"message\":\"{\\\"cba_key\\\":\\\"%d\\\"}\"}", callbackID]);
    }
    

    SDKのコールバックインタフェース(Java)
    void Login_(int callbackID){
        //  xxx,      
        UnityPlayer.UnitySendMessage("XXXSDKEventHandler", "OnLogin", "{\"funcName\":\"Receiver\",\"message\":\"{\\\"cba_key\\\":\\\"" + callbackID + "\\\"}\"}");
    }
    

    三、最後まで
    以上の内容は、UnityとiOS/AndroidのオリジナルSDKがインタラクティブになるソリューションのセットで、複雑なオリジナルSDKのインタラクティブなニーズを解決することができ、プロジェクトでも実践を経て、親測が利用できます.