unity游戏框架学习-SDK接入

概述连接:http://www.javashuo.com/article/p-nggymcxb-bw.htmlhtml

以前概述有说过SDK的大概功能以下:java

1.帐号类:建立、登陆、切换android

2.充值ios

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

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

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

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

 

1、android和c#交互.net

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);
}

2、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#同样,三个参数都是字符串类型!

3、好了。咱们知道unity跟ios\android怎么交互了,能够开始设计咱们的接口了,首先在c#端,咱们须要区分三种平台,ios\android\unity 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平台啥也不作),以下所示,U3dLogin\ShowUserCenter是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.一个接受两端回调消息的类,ios\android共用一个就行了,该类会在管理类里面初始化

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#端就完成了,而后后两端的代码

4、android端:android端渠道众多,颇有必要跟c#端同样,每一个渠道的接口都实现一个本身的实现类,再用具体的SFMainActivity去管理

android端接sdk有两种方式,两种方式的区别可参考:http://www.javashuo.com/article/p-rcxsroec-mk.html,我的倾向于使用第二种方式,由于不少系统功能在unity很差实现,但在android端却很好实现,如推送、谷歌支付等

1.将sdk的代码打成jar\aar的包导入到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文件夹下的assets\jinLibs\res三个文件夹,拷贝该工程做为咱们的as工程

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

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

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

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