教你快速高效接入SDK——Unity统一接入渠道SDK(Unity篇),sdkunity
投稿于 被查看 23054 次 评论:120
教你快速高效接入SDK——Unity统一接入渠道SDK(Unity篇),sdkunity
上一篇,我们着重讲解了用Unity开发的手游,在接入U8SDK时,Android中的部分。接下来,这一篇,我们就来看看,在Unity工程中,我们需要怎么调用上一篇中我们提供的各种接口,以及怎么接收Android中的消息通知,比如登录成功,切换帐号成功等。
在写代码之前,我们先要做一个简单的配置,在Project面板中,按照Unity官方的要求,新建一个Plugins文件夹,在Plugins文件夹下,再建立一个Android文件夹。这里,将会放置所有Android工程相关的文件。 1、将上一篇中,我们创建的工程中,将res目录拷贝到该文件夹下2、新建一个bin目录,将Android工程中bin目录下生成的jar拷贝到这里3、新建一个libs目录,将android-support-v*.jar拷贝到这里(注意,之前引入的unity的那个jar不要拷贝过来)4、将U8SDK2抽象层工程中的bin目录下生成的u8sdk2.jar拷贝到libs目录中5、将AndroidManifest.xml拷贝到Android目录下完整的结构如下:
这样,整个配置工作就完成了。接下来,我们就来看看,在Unity中怎么来完成Android中相关接口的调用以及封装。 渠道SDK接入,包括Android,IOS,WP等多种平台,这里我们需要抽象出来一个统一的上层接口,供给游戏逻辑层调用,所以我们定义一个U8SDKInterface的抽象单例类:
public abstract class U8SDKInterface{ public delegate void LoginSucHandler(U8LoginResult data); public delegate void LogoutHandler(); private static U8SDKInterface _instance; public LoginSucHandler OnLoginSuc; public LogoutHandler OnLogout; public static U8SDKInterface Instance { get { if (_instance == null) { #if UNITY_EDITOR || UNITY_STANDLONE _instance = new SDKInterfaceDefault(); #elif UNITY_ANDROID _instance = new SDKInterfaceAndroid(); #elif UNITY_IOS _instance = new SDKInterfaceIOS(); #endif } return _instance; } } //初始化 public abstract void Init(); //登录 public abstract void Login(); //自定义登录,用于腾讯应用宝,QQ登录,customData="QQ";微信登录,customData="WX" public abstract void LoginCustom(string customData); //切换帐号 public abstract void SwitchLogin(); //登出 public abstract bool Logout(); //显示个人中心 public abstract bool ShowAccountCenter(); //上传游戏数据 public abstract void SubmitGameData(U8ExtraGameData data); //调用SDK的退出确认框,返回false,说明SDK不支持退出确认框,游戏需要使用自己的退出确认框 public abstract bool SDKExit(); //调用SDK支付界面 public abstract void Pay(U8PayParams data); //SDK是否支持退出确认框 public abstract bool IsSupportExit(); //SDK是否支持用户中心 public abstract bool IsSupportAccountCenter(); //SDK是否支持登出 public abstract bool IsSupportLogout(); //去U8Server获取游戏订单号,这里逻辑是访问游戏服务器,然后游戏服务器去U8Server获取订单号 //并返回 public U8PayParams reqOrder(U8PayParams data) { //TODO 去游戏服务器获取订单号 //测试 data.orderID = "345435634534"; data.extension = "test"; return data; } }
有了这个抽象类,对于各个平台,我们需要分别实现该抽象类中的接口,从而间接地调用平台中的方法。对于Android平台,我们定义一个SDKInterfaceAndroid类:
public class SDKInterfaceAndroid : U8SDKInterface { private AndroidJavaObject jo; public SDKInterfaceAndroid() { using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); } } private T SDKCall<T>(string method, params object[] param) { try { return jo.Call<T>(method, param); } catch (Exception e) { Debug.LogError(e); } return default(T); } private void SDKCall(string method, params object[] param) { try { jo.Call(method, param); } catch (Exception e) { Debug.LogError(e); } } //这里Android中,在onCreate中直接调用了initSDK,所以这里就不用调用了 public override void Init() { //SDKCall("initSDK"); } public override void Login() { SDKCall("login"); } public override void LoginCustom(string customData) { SDKCall("loginCustom", customData); } public override void SwitchLogin() { SDKCall("switchLogin"); } public override bool Logout() { if (!IsSupportLogout()) { return false; } SDKCall("logout"); return true; } public override bool ShowAccountCenter() { if (!IsSupportAccountCenter()) { return false; } SDKCall("showAccountCenter"); return true; } public override void SubmitGameData(U8ExtraGameData data) { string json = encodeGameData(data); SDKCall("submitExtraData", json); } public override bool SDKExit() { if (!IsSupportExit()) { return false; } SDKCall("exit"); return true; } public override void Pay(U8PayParams data) { string json = encodePayParams(data); SDKCall("pay", json); } public override bool IsSupportExit() { return SDKCall<bool>("isSupportExit"); } public override bool IsSupportAccountCenter() { return SDKCall<bool>("isSupportAccountCenter"); } public override bool IsSupportLogout() { return SDKCall<bool>("isSupportLogout"); } private string encodeGameData(U8ExtraGameData data) { Dictionary<string, object> map = new Dictionary<string, object>(); map.Add("dataType", data.dataType); map.Add("roleID", data.roleID); map.Add("roleName", data.roleName); map.Add("roleLevel", data.roleLevel); map.Add("serverID", data.serverID); map.Add("serverName", data.serverName); map.Add("moneyNum", data.moneyNum); return MiniJSON.Json.Serialize(map); } private string encodePayParams(U8PayParams data) { Dictionary<string, object> map = new Dictionary<string, object>(); map.Add("productId", data.productId); map.Add("productName", data.productName); map.Add("productDesc", data.productDesc); map.Add("price", data.price); map.Add("buyNum", data.buyNum); map.Add("coinNum", data.coinNum); map.Add("serverId", data.serverId); map.Add("serverName", data.serverName); map.Add("roleId", data.roleId); map.Add("roleName", data.roleName); map.Add("roleLevel", data.roleLevel); map.Add("vip", data.vip); map.Add("orderID", data.orderID); map.Add("extension", data.extension); return MiniJSON.Json.Serialize(map); } }
首先这个类是继承了之前我们定义的U8SDKInterface抽象类,在所有的接口中,我们都通过SDKCall来间接地调用上一篇中我们定义在U8UnityContext.java中的对应接口。 之前我们说过,和Android中的通信我们采用JSON格式,所以这里你可以看到,在Unity中我们将接口需要的参数,封装成JSON格式传递过去,然后在U8UnityContext中进行解析即可。 PS:后面,等U8SDK支持IOS版本了,我们到时候再来实现SDKInterfaceIOS类。 现在,我们就来看看,游戏逻辑中,怎么调用这些接口吧。正如之前所说的,在需要登录的地方调用:U8SDKInterface.Instance.Login();需要支付的地方调用:U8SDKInterface.Instance.Pay(U8PayParams data);其他接口类似 现在部分接口调用之后,我们是希望有回调的。比如调用Login接口之后,我们就只有等待登录结果。这个是个异步的过程。所以,我们怎么在Unity来接收Android的回调通知呢? 为了能够在Unity中接收到平台的回调通知,我们需要定义一个常驻内存的GameObject,然后在GameObject身上绑定一个负责通知回调的脚本,在脚本中定义一系列回调的函数。 还记得,在上一篇中,我们在U8UnityContext中,定义了一个一系列常量,包括如下: public final static String CALLBACK_GAMEOBJECT_NAME = “(u8sdk_callback)”;
public final static String CALLBACK_INIT = “OnInitSuc”;
public final static String CALLBACK_LOGIN = “OnLoginSuc”;
public final static String CALLBACK_SWITCH_LOGIN = “OnSwitchLogin”;
public final static String CALLBACK_LOGOUT = “OnLogout”; public final static String CALLBACK_PAY = “OnPaySuc”; 其中,CALLBACK_GAMEOBJECT_NAME就是Unity中这个负责接收回调通知的GameObject的名称,而下面几个就是回调脚本中需要定义的函数的函数名称。 所以,接下来,我们就定义一个专门负责回调的脚本:
public class U8SDKCallback : MonoBehaviour { private static U8SDKCallback _instance; private static object _lock = new object(); //初始化回调对象 public static U8SDKCallback InitCallback() { UnityEngine.Debug.LogError("Callback->InitCallback"); lock (_lock) { if (_instance == null) { GameObject callback = GameObject.Find("(u8sdk_callback)"); if (callback == null) { callback = new GameObject("(u8sdk_callback)"); UnityEngine.Object.DontDestroyOnLoad(_instance); _instance = callback.AddComponent<U8SDKCallback>(); } else { _instance = callback.GetComponent<U8SDKCallback>(); } } return _instance; } } //初始化成功回调 public void OnInitSuc() { //一般不需要处理 UnityEngine.Debug.LogError("Callback->OnInitSuc"); } //登录成功回调 public void OnLoginSuc(string jsonData) { UnityEngine.Debug.LogError("Callback->OnLoginSuc"); U8LoginResult data = parseLoginResult(jsonData); if (data == null) { UnityEngine.Debug.LogError("The data parse error." + jsonData); return; } if (U8SDKInterface.Instance.OnLoginSuc != null) { U8SDKInterface.Instance.OnLoginSuc.Invoke(data); } } //切换帐号回调 public void OnSwitchLogin() { UnityEngine.Debug.LogError("Callback->OnSwitchLogin"); if (U8SDKInterface.Instance.OnLogout != null) { U8SDKInterface.Instance.OnLogout.Invoke(); } } //登出回调 public void OnLogout() { UnityEngine.Debug.LogError("Callback->OnLogout"); if (U8SDKInterface.Instance.OnLogout != null) { U8SDKInterface.Instance.OnLogout.Invoke(); } } //支付回调,网游不需要实现该接口,该接口用于单机游戏 public void OnPaySuc(string jsonData) { //Nothing... } private U8LoginResult parseLoginResult(string str) { object jsonParsed = MiniJSON.Json.Deserialize(str); if (jsonParsed != null) { Dictionary<string, object> jsonMap = jsonParsed as Dictionary<string, object>; U8LoginResult data = new U8LoginResult(); if (jsonMap.ContainsKey("isSuc")) { data.isSuc = bool.Parse(jsonMap["isSuc"].ToString()); } if (jsonMap.ContainsKey("isSwitchAccount")) { data.isSwitchAccount = bool.Parse(jsonMap["isSwitchAccount"].ToString()); } if (jsonMap.ContainsKey("userID")) { data.userID = jsonMap["userID"].ToString(); } if (jsonMap.ContainsKey("sdkUserID")) { data.sdkUserID = jsonMap["sdkUserID"].ToString(); } if (jsonMap.ContainsKey("username")) { data.username = jsonMap["username"].ToString(); } if (jsonMap.ContainsKey("sdkUsername")) { data.sdkUsername = jsonMap["sdkUsername"].ToString(); } if (jsonMap.ContainsKey("token")) { data.token = jsonMap["token"].ToString(); } return data; } return null; } }
在游戏运行的最开始的时候,记得调用U8SDKCallback.InitCallback来进行初始化,自动创建一个负责回调的GameObject,同时将该脚本绑定到这个对象上。 到这里,U8SDK在Unity中的封装基本就算完成了,接下来,我们就来测试下接口的调用。我们用UGUI建立一个建立一个简单的面板,然后包含一个登录按钮和支付按钮,然后通过绑定一个ClickObject.cs脚本来简体按钮的响应事件:
public class ClickObject : MonoBehaviour { // Use this for initialization private Text txtState; void Start () { U8SDKCallback.InitCallback(); GameObject loginObj = GameObject.Find("BtnLogin"); Button btnLogin = loginObj.GetComponent<Button>(); btnLogin.onClick.AddListener(delegate() { OnLoginClick(); }); GameObject payObj = GameObject.Find("BtnPay"); Button btnPay = payObj.GetComponent<Button>(); btnPay.onClick.AddListener(delegate() { OnPayClick(); }); GameObject stateObj = GameObject.Find("TxtState"); txtState = stateObj.GetComponent<Text>(); U8SDKInterface.Instance.OnLoginSuc = delegate(U8LoginResult result) { OnLoginSuc(result); }; U8SDKInterface.Instance.OnLogout = delegate() { OnLogout(); }; } void Update() { if (Input.GetKeyUp(KeyCode.Escape)) { if (!U8SDKInterface.Instance.SDKExit()) { //TODO 退出确认框 Application.Quit(); } } } void OnLoginSuc(U8LoginResult result) { if (!result.isSuc) { txtState.text = "登录失败"; return; } if (result.isSwitchAccount) { txtState.text = "切换帐号成功:" + result.token; } else { txtState.text = "登录成功:" + result.token; } } void OnLogout() { txtState.text = "未登录"; } void OnLoginClick() { U8SDKInterface.Instance.Login(); } void OnPayClick() { U8PayParams data = new U8PayParams(); data.productId = "1"; data.productName = "元宝"; data.productDesc = "购买100元宝,赠送20元宝"; data.price = 100; data.buyNum = 1; data.coinNum = 300; data.serverId = "10"; data.serverName = "地狱之恋"; data.roleId = "u8_24532452"; data.roleName = "麻利麻利吼"; data.roleLevel = 15; data.vip = "v15"; data = U8SDKInterface.Instance.reqOrder(data); U8SDKInterface.Instance.Pay(data); } }
好了,到这里,我们已经演示了,如何在Unity开发的手游中,完成U8SDK接口的调用和封装。完整的demo演示可以点击这里下载:HERE
好了,如果你对U8SDK感兴趣,欢迎访问U8SDK的官方网站深入了解哦。(HERE)
版权声明:本文为博主原创文章,未经博主允许不得转载。
用户评论