当前位置:   article > 正文

教你快速高效接入SDK——Unity统一接入渠道SDK(Unity篇)_unity接渠道包

unity接渠道包

上一篇,我们着重讲解了用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的抽象单例类:

  1. public abstract class U8SDKInterface{
  2. public delegate void LoginSucHandler(U8LoginResult data);
  3. public delegate void LogoutHandler();
  4. private static U8SDKInterface _instance;
  5. public LoginSucHandler OnLoginSuc;
  6. public LogoutHandler OnLogout;
  7. public static U8SDKInterface Instance
  8. {
  9. get
  10. {
  11. if (_instance == null)
  12. {
  13. #if UNITY_EDITOR || UNITY_STANDLONE
  14. _instance = new SDKInterfaceDefault();
  15. #elif UNITY_ANDROID
  16. _instance = new SDKInterfaceAndroid();
  17. #elif UNITY_IOS
  18. _instance = new SDKInterfaceIOS();
  19. #endif
  20. }
  21. return _instance;
  22. }
  23. }
  24. //初始化
  25. public abstract void Init();
  26. //登录
  27. public abstract void Login();
  28. //自定义登录,用于腾讯应用宝,QQ登录,customData="QQ";微信登录,customData="WX"
  29. public abstract void LoginCustom(string customData);
  30. //切换帐号
  31. public abstract void SwitchLogin();
  32. //登出
  33. public abstract bool Logout();
  34. //显示个人中心
  35. public abstract bool ShowAccountCenter();
  36. //上传游戏数据
  37. public abstract void SubmitGameData(U8ExtraGameData data);
  38. //调用SDK的退出确认框,返回false,说明SDK不支持退出确认框,游戏需要使用自己的退出确认框
  39. public abstract bool SDKExit();
  40. //调用SDK支付界面
  41. public abstract void Pay(U8PayParams data);
  42. //SDK是否支持退出确认框
  43. public abstract bool IsSupportExit();
  44. //SDK是否支持用户中心
  45. public abstract bool IsSupportAccountCenter();
  46. //SDK是否支持登出
  47. public abstract bool IsSupportLogout();
  48. //去U8Server获取游戏订单号,这里逻辑是访问游戏服务器,然后游戏服务器去U8Server获取订单号
  49. //并返回
  50. public U8PayParams reqOrder(U8PayParams data)
  51. {
  52. //TODO 去游戏服务器获取订单号
  53. //测试
  54. data.orderID = "345435634534";
  55. data.extension = "test";
  56. return data;
  57. }
  58. }

有了这个抽象类,对于各个平台,我们需要分别实现该抽象类中的接口,从而间接地调用平台中的方法。对于Android平台,我们定义一个SDKInterfaceAndroid类:
  1. public class SDKInterfaceAndroid : U8SDKInterface
  2. {
  3. private AndroidJavaObject jo;
  4. public SDKInterfaceAndroid()
  5. {
  6. using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
  7. {
  8. jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
  9. }
  10. }
  11. private T SDKCall<T>(string method, params object[] param)
  12. {
  13. try
  14. {
  15. return jo.Call<T>(method, param);
  16. }
  17. catch (Exception e)
  18. {
  19. Debug.LogError(e);
  20. }
  21. return default(T);
  22. }
  23. private void SDKCall(string method, params object[] param)
  24. {
  25. try
  26. {
  27. jo.Call(method, param);
  28. }
  29. catch (Exception e)
  30. {
  31. Debug.LogError(e);
  32. }
  33. }
  34. //这里Android中,在onCreate中直接调用了initSDK,所以这里就不用调用了
  35. public override void Init()
  36. {
  37. //SDKCall("initSDK");
  38. }
  39. public override void Login()
  40. {
  41. SDKCall("login");
  42. }
  43. public override void LoginCustom(string customData)
  44. {
  45. SDKCall("loginCustom", customData);
  46. }
  47. public override void SwitchLogin()
  48. {
  49. SDKCall("switchLogin");
  50. }
  51. public override bool Logout()
  52. {
  53. if (!IsSupportLogout())
  54. {
  55. return false;
  56. }
  57. SDKCall("logout");
  58. return true;
  59. }
  60. public override bool ShowAccountCenter()
  61. {
  62. if (!IsSupportAccountCenter())
  63. {
  64. return false;
  65. }
  66. SDKCall("showAccountCenter");
  67. return true;
  68. }
  69. public override void SubmitGameData(U8ExtraGameData data)
  70. {
  71. string json = encodeGameData(data);
  72. SDKCall("submitExtraData", json);
  73. }
  74. public override bool SDKExit()
  75. {
  76. if (!IsSupportExit())
  77. {
  78. return false;
  79. }
  80. SDKCall("exit");
  81. return true;
  82. }
  83. public override void Pay(U8PayParams data)
  84. {
  85. string json = encodePayParams(data);
  86. SDKCall("pay", json);
  87. }
  88. public override bool IsSupportExit()
  89. {
  90. return SDKCall<bool>("isSupportExit");
  91. }
  92. public override bool IsSupportAccountCenter()
  93. {
  94. return SDKCall<bool>("isSupportAccountCenter");
  95. }
  96. public override bool IsSupportLogout()
  97. {
  98. return SDKCall<bool>("isSupportLogout");
  99. }
  100. private string encodeGameData(U8ExtraGameData data)
  101. {
  102. Dictionary<string, object> map = new Dictionary<string, object>();
  103. map.Add("dataType", data.dataType);
  104. map.Add("roleID", data.roleID);
  105. map.Add("roleName", data.roleName);
  106. map.Add("roleLevel", data.roleLevel);
  107. map.Add("serverID", data.serverID);
  108. map.Add("serverName", data.serverName);
  109. map.Add("moneyNum", data.moneyNum);
  110. return MiniJSON.Json.Serialize(map);
  111. }
  112. private string encodePayParams(U8PayParams data)
  113. {
  114. Dictionary<string, object> map = new Dictionary<string, object>();
  115. map.Add("productId", data.productId);
  116. map.Add("productName", data.productName);
  117. map.Add("productDesc", data.productDesc);
  118. map.Add("price", data.price);
  119. map.Add("buyNum", data.buyNum);
  120. map.Add("coinNum", data.coinNum);
  121. map.Add("serverId", data.serverId);
  122. map.Add("serverName", data.serverName);
  123. map.Add("roleId", data.roleId);
  124. map.Add("roleName", data.roleName);
  125. map.Add("roleLevel", data.roleLevel);
  126. map.Add("vip", data.vip);
  127. map.Add("orderID", data.orderID);
  128. map.Add("extension", data.extension);
  129. return MiniJSON.Json.Serialize(map);
  130. }
  131. }

首先这个类是继承了之前我们定义的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的名称,而下面几个就是回调脚本中需要定义的函数的函数名称。
 
所以,接下来,我们就定义一个专门负责回调的脚本:

  1. public class U8SDKCallback : MonoBehaviour
  2. {
  3. private static U8SDKCallback _instance;
  4. private static object _lock = new object();
  5. //初始化回调对象
  6. public static U8SDKCallback InitCallback()
  7. {
  8. UnityEngine.Debug.LogError("Callback->InitCallback");
  9. lock (_lock)
  10. {
  11. if (_instance == null)
  12. {
  13. GameObject callback = GameObject.Find("(u8sdk_callback)");
  14. if (callback == null)
  15. {
  16. callback = new GameObject("(u8sdk_callback)");
  17. UnityEngine.Object.DontDestroyOnLoad(_instance);
  18. _instance = callback.AddComponent<U8SDKCallback>();
  19. }
  20. else
  21. {
  22. _instance = callback.GetComponent<U8SDKCallback>();
  23. }
  24. }
  25. return _instance;
  26. }
  27. }
  28. //初始化成功回调
  29. public void OnInitSuc()
  30. {
  31. //一般不需要处理
  32. UnityEngine.Debug.LogError("Callback->OnInitSuc");
  33. }
  34. //登录成功回调
  35. public void OnLoginSuc(string jsonData)
  36. {
  37. UnityEngine.Debug.LogError("Callback->OnLoginSuc");
  38. U8LoginResult data = parseLoginResult(jsonData);
  39. if (data == null)
  40. {
  41. UnityEngine.Debug.LogError("The data parse error." + jsonData);
  42. return;
  43. }
  44. if (U8SDKInterface.Instance.OnLoginSuc != null)
  45. {
  46. U8SDKInterface.Instance.OnLoginSuc.Invoke(data);
  47. }
  48. }
  49. //切换帐号回调
  50. public void OnSwitchLogin()
  51. {
  52. UnityEngine.Debug.LogError("Callback->OnSwitchLogin");
  53. if (U8SDKInterface.Instance.OnLogout != null)
  54. {
  55. U8SDKInterface.Instance.OnLogout.Invoke();
  56. }
  57. }
  58. //登出回调
  59. public void OnLogout()
  60. {
  61. UnityEngine.Debug.LogError("Callback->OnLogout");
  62. if (U8SDKInterface.Instance.OnLogout != null)
  63. {
  64. U8SDKInterface.Instance.OnLogout.Invoke();
  65. }
  66. }
  67. //支付回调,网游不需要实现该接口,该接口用于单机游戏
  68. public void OnPaySuc(string jsonData)
  69. {
  70. //Nothing...
  71. }
  72. private U8LoginResult parseLoginResult(string str)
  73. {
  74. object jsonParsed = MiniJSON.Json.Deserialize(str);
  75. if (jsonParsed != null)
  76. {
  77. Dictionary<string, object> jsonMap = jsonParsed as Dictionary<string, object>;
  78. U8LoginResult data = new U8LoginResult();
  79. if (jsonMap.ContainsKey("isSuc"))
  80. {
  81. data.isSuc = bool.Parse(jsonMap["isSuc"].ToString());
  82. }
  83. if (jsonMap.ContainsKey("isSwitchAccount"))
  84. {
  85. data.isSwitchAccount = bool.Parse(jsonMap["isSwitchAccount"].ToString());
  86. }
  87. if (jsonMap.ContainsKey("userID"))
  88. {
  89. data.userID = jsonMap["userID"].ToString();
  90. }
  91. if (jsonMap.ContainsKey("sdkUserID"))
  92. {
  93. data.sdkUserID = jsonMap["sdkUserID"].ToString();
  94. }
  95. if (jsonMap.ContainsKey("username"))
  96. {
  97. data.username = jsonMap["username"].ToString();
  98. }
  99. if (jsonMap.ContainsKey("sdkUsername"))
  100. {
  101. data.sdkUsername = jsonMap["sdkUsername"].ToString();
  102. }
  103. if (jsonMap.ContainsKey("token"))
  104. {
  105. data.token = jsonMap["token"].ToString();
  106. }
  107. return data;
  108. }
  109. return null;
  110. }
  111. }

在游戏运行的最开始的时候,记得调用U8SDKCallback.InitCallback来进行初始化,自动创建一个负责回调的GameObject,同时将该脚本绑定到这个对象上。
 
到这里,U8SDK在Unity中的封装基本就算完成了,接下来,我们就来测试下接口的调用。我们用UGUI建立一个建立一个简单的面板,然后包含一个登录按钮和支付按钮,然后通过绑定一个ClickObject.cs脚本来简体按钮的响应事件:

  1. public class ClickObject : MonoBehaviour {
  2. // Use this for initialization
  3. private Text txtState;
  4. void Start () {
  5. U8SDKCallback.InitCallback();
  6. GameObject loginObj = GameObject.Find("BtnLogin");
  7. Button btnLogin = loginObj.GetComponent<Button>();
  8. btnLogin.onClick.AddListener(delegate()
  9. {
  10. OnLoginClick();
  11. });
  12. GameObject payObj = GameObject.Find("BtnPay");
  13. Button btnPay = payObj.GetComponent<Button>();
  14. btnPay.onClick.AddListener(delegate()
  15. {
  16. OnPayClick();
  17. });
  18. GameObject stateObj = GameObject.Find("TxtState");
  19. txtState = stateObj.GetComponent<Text>();
  20. U8SDKInterface.Instance.OnLoginSuc = delegate(U8LoginResult result)
  21. {
  22. OnLoginSuc(result);
  23. };
  24. U8SDKInterface.Instance.OnLogout = delegate()
  25. {
  26. OnLogout();
  27. };
  28. }
  29. void Update()
  30. {
  31. if (Input.GetKeyUp(KeyCode.Escape))
  32. {
  33. if (!U8SDKInterface.Instance.SDKExit())
  34. {
  35. //TODO 退出确认框
  36. Application.Quit();
  37. }
  38. }
  39. }
  40. void OnLoginSuc(U8LoginResult result)
  41. {
  42. if (!result.isSuc)
  43. {
  44. txtState.text = "登录失败";
  45. return;
  46. }
  47. if (result.isSwitchAccount)
  48. {
  49. txtState.text = "切换帐号成功:" + result.token;
  50. }
  51. else
  52. {
  53. txtState.text = "登录成功:" + result.token;
  54. }
  55. }
  56. void OnLogout()
  57. {
  58. txtState.text = "未登录";
  59. }
  60. void OnLoginClick()
  61. {
  62. U8SDKInterface.Instance.Login();
  63. }
  64. void OnPayClick()
  65. {
  66. U8PayParams data = new U8PayParams();
  67. data.productId = "1";
  68. data.productName = "元宝";
  69. data.productDesc = "购买100元宝,赠送20元宝";
  70. data.price = 100;
  71. data.buyNum = 1;
  72. data.coinNum = 300;
  73. data.serverId = "10";
  74. data.serverName = "地狱之恋";
  75. data.roleId = "u8_24532452";
  76. data.roleName = "麻利麻利吼";
  77. data.roleLevel = 15;
  78. data.vip = "v15";
  79. data = U8SDKInterface.Instance.reqOrder(data);
  80. U8SDKInterface.Instance.Pay(data);
  81. }
  82. }

好了,到这里,我们已经演示了,如何在Unity开发的手游中,完成U8SDK接口的调用和封装。完整的demo演示可以点击这里下载: HERE

好了,如果你对U8SDK感兴趣,欢迎访问U8SDK的官方网站深入了解哦。 (HERE)


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/323085
推荐阅读
相关标签
  

闽ICP备14008679号