0评论

Unity多渠道SDK接入与安卓通信

文章来自CSDN博客 2018-10-17 13浏览
我们要接入多个渠道,所以就需要先将SDK的功能抽象出来。SDK基本功能主要有登录、登出、支付,有的还有角色数据上报等功能。

我们先声明一个抽象类,具体如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class SdkBaseClass
{
    protected bool isLogin = false;
    /// <summary>
    /// 初始化Sdk
    /// </summary>
    public abstract void Initialization();
    /// <summary>
    /// 设置监听对象名称
    /// </summary>
    /// <param name="objName"></param>
    public abstract void AddListener(string objName);
    /// <summary>
    /// 游戏登陆
    /// </summary>
    public abstract void Login();
    /// <summary>
    /// 登陆回调结果
    /// </summary>
    /// <param name="result"></param>
    public abstract void LoginResult(string result);
    /// <summary>
    /// 游戏登出
    /// </summary>
    public abstract void Logout();
    /// <summary>
    /// 游戏登出回调结果
    /// </summary>
    /// <param name="result"></param>
    public abstract void LogoutResult(string result);
    /// <summary>
    /// 商品支付
    /// </summary>
    /// <param name="paras"></param>
    public abstract void Pay(params object[] paras);
    /// <summary>
    /// 支付回调
    /// </summary>
    /// <param name="result"></param>
    public abstract void PayResult(string result);
    /// <summary>
    /// 玩家数据上报接口
    /// </summary>
    /// <param name="paras"></param>
    public abstract void SetData(params object[] paras);
    /// <summary>
    /// 调用Java类实现
    /// </summary>
    /// <param name="funcName"></param>
    /// <param name="paras"></param>
    protected void Cs2Java(string funcName, params object[] paras)
    {
        using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"))
            {
                jo.Call(funcName, paras);
            }
        }
    }
}

1.我们新建一个AS工程项目,注意包名要配置于你的unity项目的包名相同。


2.最低sdk版本按照你本身需求来选择就好了。

3.然后选择空项目

4.这里我们不需要安卓的ui界面,所以取消Layout File的钩子。

5.在build.gradle中将“com.android.application“改为”com.android.library",同时注释applicationId这一行代码。


6.从"Unity安装目录\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes"找到classes.jar文件拷贝至AS项目中的app\libs目录下,然后视图选项由Android改为Project,在app\libs目录下找到刚刚拷贝的classes.jar,然后右键鼠标选择Add as Library点确定,然后切回Android视窗,导入成功后可在build.gradle中看见classser成功被引用了。

7.安卓端修改MainActivity,继承自UnityPlayerActivity,具体代码如下:
package com.myapp.sdkdemo;
import android.os.Bundle;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
import org.json.JSONObject;
public class MainActivity extends UnityPlayerActivity {
    String objName="";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    public void AddListener(String name)
    {
        this.objName=name;
    }
    public void Login()
    {
        //登录
        LoginCallback();
    }
    //登录回调演示
    void LoginCallback()
    {
        int code=1;
        int uid=1;
        String token="abcdefg";
        JSONObject json = new JSONObject();
        try
        {
            if (code==1)
            {
                json.put("uid", uid);
                json.put("token",token);
            }
            json.put("code",code);
            UnityPlayer.UnitySendMessage(objName,"LoginResult",json.toString());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    public void Pay(String productId,int price,String extra,String roleId,String serverId)
    {
        PayCallback();
    }
    //支付回调演示
    void PayCallback()
    {
        int code=1;
        JSONObject json = new JSONObject();
        try
        {
            json.put("code",code);
            UnityPlayer.UnitySendMessage(objName,"PayResult",json.toString());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Unity端,Sdk实际实现如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LitJson;
public class MySdk : SdkBaseClass
{
    public override void AddListener(string objName)
    {
        Cs2Java("AddListener", objName);
    }
    public override void Initialization()
    {
        Cs2Java("Init");
    }
    public override void Login()
    {
        Cs2Java("Login");
    }
    public override void LoginResult(string result)
    {
        JsonData recvData = JsonMapper.ToObject(result);
        int code = (int)recvData["code"];
        switch (code)
        {
            case 1:
                Debug.LogWarning("uid:" + recvData["uid"] + "\n"
                            + "token:" + recvData["token"]);
                break;
            case 2:
                Debug.LogWarning("登录失败");
                break;
        }
    }
    public override void Logout()
    {
        if (!isLogin) return;
        //...
    }
    public override void LogoutResult(string result)
    {
        isLogin = false;
        //....
    }
    public override void Pay(params object[] paras)
    {
        Cs2Java("Pay",paras);
    }
    public override void PayResult(string result)
    {
        JsonData recvData = JsonMapper.ToObject(result);
        int code = (int)recvData["code"];
        switch (code)
        {
            case 1:
                Debug.LogWarning("支付成功");
                break;
            case 2:
                Debug.LogWarning("支付取消");
                break;
            case 3:
                Debug.LogWarning("支付失败");
                break;
        }
    }
    public override void SetData(params object[] paras)
    {
        //...
    }
}

Unity端,SdkManager具体实现如下,还有很多重复的地方就不多写了,基本大同小异。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SdkManager : MonoBehaviour {
    static SdkManager _instance;
    SdkBaseClass sdkClass;
    public static SdkManager Instance
    {
        get
        {
            return _instance;
        }
    }
    void Awake()
    {
        _instance = this;
        sdkClass = new MySdk();
        sdkClass.AddListener(this.gameObject.name);
    }
	void Start ()
    {
        sdkClass.Initialization();
	}
    public void Login()
    {
        sdkClass.Login();
    }
    public void LoginResult(string result)
    {
        sdkClass.LoginResult(result);
    }
    public void Pay(string productId, int price, string extra, string roleId, string serverId)
    {
        sdkClass.Pay(productId, price, extra, roleId, serverId);
    }
    public void PayResult(string result)
    {
        sdkClass.PayResult(result);
    }
}

写个测试脚本挂上去试一下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestScript : MonoBehaviour {
    public void Login()
    {
        SdkManager.Instance.Login();
    }
    public void Pay()
    {
        SdkManager.Instance.Pay("goods.01", 1, "null", "role.01", "s1");
    }
}

同时Rebuild Project AS项目,生成AAR包位于“项目路径\app\build\outputs\aar”中,提取aar包中的classes.jar文件和AndroidManifest.xml文件。修改AndroidManifest的application标签,如果有其他配置请自行修改配置。修改后文件如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.myapp.sdkdemo"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="27" />
    <application
        android:allowBackup="true"
        android:theme="@style/UnityThemeSelector"
        android:icon="@drawable/app_icon"
        android:label="@string/app_name"
        android:debuggable="true">
        <activity android:name="com.myapp.sdkdemo.MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

我们使用蓝叠和AS自带的logcat看下log记录,若as中logcat无法连接到蓝叠,可是用adb工具命令连接
adb connect localhost:5555

点击登录和支付,我们看到Logcat中显示了回调消息,说明通信成功了。


到此为止我们多渠道接入就完成了,如果有新的sdk接入仅仅需要新建一个脚本继承自SdkBaseClass,然后在自身类中实现就可以了,SdkManager中可以使用宏,然后根据宏来选择使用的参数和sdk类。来自:https://blog.csdn.net/RinKas/article/details/81001543