zoukankan      html  css  js  c++  java
  • unity游戏框架学习-SDK接入

    概述链接:https://www.cnblogs.com/wang-jin-fu/p/10975660.html

    之前概述有说过SDK的大概功能如下:

    1.账号类:创建、登录、切换

    2.充值

    3.外部分享如微信、朋友圈、FB等

    4.打开外部链接,如论坛、社区、反馈等

    5.功能类:语音、头像、埋点

    这些功能都是sdk提供的,而我们要做的就是调用sdk的接口(ios的OC接口,android的java接口)

    一、android和c#交互

    1.c#调用android方法,如下,使用 AndroidJavaClass获取AndroidJavaObject对象,在通过AndroidJavaObject调用java方法。最常用的是AndroidJavaObject的Call方法,unity文档:http://docs.unity3d.com/ScriptReference/AndroidJavaObject.html
    这个Call是支持多参数的,第一个参数必须是方法名,第二个开始则是各种参数。如果有返回值则需要使用泛型版本Call<Type>。

    using UnityEngine;
    
    /// <summary>
    /// Android帮助库
    /// 提供unity对android端的调用,属性的get和set麻烦封装成方法
    /// </summary>
    public class AndroidHelper
    {
        const string AndroidMainActivity = "com.unity3d.player.UnityPlayer";

    static AndroidJavaObject ms_MainActivity; public static AndroidJavaObject MainActivity { get { if (ms_MainActivity == null) { AndroidJavaClass jc = new AndroidJavaClass (AndroidMainActivity); if (jc != null) { ms_MainActivity = jc.GetStatic<AndroidJavaObject> ("currentActivity"); } } return ms_MainActivity; } } #region MainActivity的非静态方法 public static void Call(string method) { MainActivity.Call(method); } public static void Call(string method, object[] args) { MainActivity.Call(method, args); } public static void Call(string method, bool val) { MainActivity.Call(method, new object[] { val }); } public static void Call(string method, string val) { MainActivity.Call(method, new object[] { val }); } public static string CallWithReturn(string method) { string result = ""; AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); result = jo.Call<string>(method); return result; } #endregion #region MainActivity的静态方法 public static void CallStatic(string method) { MainActivity.CallStatic(method); } public static void CallStatic(string method, string val) { MainActivity.CallStatic(method, new object[] { val }); } public static string CallStaticWithReturn(string val) { string result = ""; AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); result = jo.CallStatic<string>(val); return result; } #endregion }

    2.Java回调unity,public static void UnitySendMessage(String var0, String var1, String var2) ,第一个参数为unity中的一个gameobject名称,第二个参数为这个gameobject身上捆绑的脚本中的一个方法,而第三参数是这个对应方法上的参数

    public static final String UNITY_HANDLER = "SDKMsgHandler";
    **
     * 向Unity传送
    * @param arg1 函数名
    * @param arg2 参数
    */
    public static void UnitySendMessage(String arg1, String arg2)
    {
         UnityPlayer.UnitySendMessage(UNITY_HANDLER, arg1, arg2);
    }

    二、ios和c#的交互,可以参照官网:https://docs.unity3d.com/Manual/PluginsForIOS.html,你需要把你的oc代码放在Plugins/iOS文件夹下才能正确调用到OC的代码

    c#调用ios:c#端

    [DllImport("__Internal")]
    private static extern string U3dGetAvailableDiskSize();
    
    /// <summary>
    /// 获取磁盘空间
    /// </summary>
    public long GetAvailableDiskSize()
    {
        string size = U3dGetAvailableDiskSize();
        return long.Parse(size);
    }

    OC端

    char* _MakeStringCopy( const char* string)
    {
        if (NULL == string) {
            return NULL;
        }
        char* res = (char*)malloc(strlen(string)+1);
        strcpy(res, string);
        return res;
    }
    
    const char* U3dGetAvailableDiskSize()
    {
        struct statfs buf;
        long long freespace = -1;
        if(statfs("/var", &buf) >= 0)
        {
            freespace = (long long)(buf.f_bsize * buf.f_bfree);
        }
        NSString *_msg = [NSString stringWithFormat:@"%lld", freespace];
        
        return _MakeStringCopy([_msg UTF8String]);
    }

    2.OC回调unity:

    UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");
    参数1:gameobject名字;参数2:回调函数的名字;参数3:参数。同android开发中java回调c#一样,三个参数都是字符串类型!

    三、好了。我们知道unity跟iosandroid怎么交互了,可以开始设计我们的接口了,首先在c#端,我们需要区分三种平台,iosandroidunity editor三种平台,我们不可能像下面这么写,几十个接口如果都这么写,会原地爆炸的,所以我们需要用的接口来规范我们的代码

    if(platform == ios)
    {
        //xxxx
    }else if(paltform == android)
    {
        //xxxx
    }else if(platform == editor){
        //xxxx
    }

    1.首先我们需要有一个接口类:

    public interface SDKInterface
    {
        /** 登录 **/
        void Login();
    
        /** 打开SDK用户中心界 **/
        void ShowUserCenter();
    }

    2.我们需要有每个平台的具体实现类(其实就是ios调用OC,android调用Java,editor平台啥也不做),如下所示,U3dLoginShowUserCenter是Ios、android两端的实现代码,这里就不上了

    #if UNITY_ANDROID
    public class AndroidSDK : SDKInterface
    {
        /// <summary>
        /// 登录
        /// </summary>
        public void Login()
        {
            Call("U3dLogin");
        }
    
        /// <summary>
        /// 打开SDK用户中心界
        /// </summary>
        public void ShowUserCenter()
        {
            Call("U3dShowUserCenter");
        }
    }
    #endif
    #if UNITY_IOS
    public class IOSSDK : SDKInterface
    {
        [DllImport("__Internal")]
        private static extern void U3dLogin();
    
        [DllImport("__Internal")]
        private static extern void U3dShowUserCenter();
    
        /// <summary>
        /// 登录
        /// </summary>
        public void Login()
        {
            U3dLogin();
        }
    
        /// <summary>
        /// 打开SDK用户中心界
        /// </summary>
        public void ShowUserCenter()
        {
            U3dShowUserCenter();
        }
    }
    #endif
    public class EmptySDK : SDKInterface
    {
        public void Login() { }
    
        public void ShowUserCenter() { }
    }

    3.一个接受两端回调消息的类,iosandroid共用一个就好了,该类会在管理类里面初始化

    public class SDKMsgHandler : MonoBehaviour
    {
        /// <summary>
        /// 登录回调
        /// </summary>
        /// <param name="msg">msg</param>
        public void LoginNotification(string msg)
        {        
        Debug.Log("登录回调:" + msg);
        }
    }

    4.我们需要一个管理类,来确定具体是调用哪一个接口

    public class SDKModule : ModuleBase
    {
        public SDKModule ()
        {
            #if UNITY_EDITOR || GUIDE
            _sdk = new EmptySDK ();
            #elif UNITY_IOS
            _sdk = new IOSSDK();
            #elif UNITY_ANDROID
            _sdk = new AndroidSDK();
            #else
            _sdk = new EmptySDK();
            #endif
    
            GameObject go = new GameObject ("SDKMsgHandler");
            GameObject.DontDestroyOnLoad (go);
            go.AddComponent<SDKMsgHandler> ();
        }
    
        /// <summary>
        /// 登录
        /// </summary>
        public void Login ()
        {
            Debug.Log("Login c");
            _sdk.Login ();
        }
    
        /// <summary>
        /// 打开SDK用户中心界
        /// </summary>
        public void ShowUserCenter ()
        {
            Debug.Log("ShowUserCenter c");
            _sdk.ShowUserCenter ();
        }
    }

    至此,c#端就完成了,然后后两端的代码

    四、android端:android端渠道众多,很有必要跟c#端一样,每个渠道的接口都实现一个自己的实现类,再用具体的SFMainActivity去管理

    android端接sdk有两种方式,两种方式的区别可参考:https://blog.csdn.net/yang8456211/article/details/51356193,个人倾向于使用第二种方式,因为很多系统功能在unity不好实现,但在android端却很好实现,如推送、谷歌支付等

    1.将sdk的代码打成jaraar的包导入到unity.

    android studio(as)导出aar可参考:https://www.jianshu.com/p/b059e84e85d1

    android studio(as)导出jar可参考:https://www.jianshu.com/p/8256c0da444a

    2.将unity导出到android studio,在使用as打apk

       (1)将unity导出的项目,删除其中的src/main文件夹下的assetsjinLibs es三个文件夹,拷贝该工程作为我们的as工程

     (2)新建一个java类SFMainActivity,该类继承自UnityPlayerActivity,该类的职责类似于前面的SDKModule,负责sdk的初始化(例如语言、版本等需要通知渠道方的)和unity接口的封装,前面AndroidSDK即调用的是这个类的方法

        (3)新建一个sdk的接口类,该类和SDKInterface接口一致,新建不同渠道的实现类,实现类继承自接口类,完成具体的sdk功能

        (4)打包的时候只需要把第一步删除的内容拷贝到我们的备份as工程就好了

    五、ios端,ios端相对android端没有这么多渠道,相对会简单一些,我们只需要把OC的代码放在Plugins/iOS文件夹就好了(需要注意OC语法的参数类型转换)

  • 相关阅读:
    ORACLE 查看进程数,已执行任务数, 剩余任务数,删除指定任务
    ORACLE 收集统计整个用户数据
    解决Hystrix dashboard Turbine 一直 Loading…… 及其他坑
    利用 Maven 构造 Spring Cloud 微服务架构 模块使用 spring Boot构建
    AES加解密
    JAVA POI XSSFWorkbook导出扩展名为xlsx的Excel,附带weblogic 项目导出Excel文件错误的解决方案
    JAVA 文件的上传下载
    shell启停服务脚本模板
    JAVA 设计模式之 原型模式详解
    JAVA 设计模式之 工厂模式详解
  • 原文地址:https://www.cnblogs.com/wang-jin-fu/p/11017653.html
Copyright © 2011-2022 走看看