Unity多渠道SDK接入与安卓通信
发表于2018-10-17
我们要接入多个渠道,所以就需要先将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