您现在的位置是:首页 > 文章详情

ASCSDK-------通用包接入文档(UNITY篇)

日期:2018-04-20点击:275

1. Untiy接入文档------Android端

  • Android端的作用是对接ASCSDK打包工具与unity原生端的中间件。
  • ASCUnityContext是主要的连接类,这个类继承UnityPlayerActivity ,也是游戏的启动Activity。
package com.asc.sdk; import java.util.List; import org.json.JSONException; import org.json.JSONObject; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.widget.Toast; import com.asc.sdk.platform.ASCExitListener; import com.asc.sdk.platform.ASCInitListener; import com.asc.sdk.platform.ASCPlatform; import com.asc.sdk.plugin.ASCUser; import com.asc.sdk.verify.UToken; import com.unity3d.player.UnityPlayer; import com.unity3d.player.UnityPlayerActivity; /*** * 记得将游戏工程中的AndroidManifest.xml中application节点,增加一个android:name="ASCApplication" * 如果游戏有自己的Application。那么通过实现IApplicationListener接口来实现,而不要使用继承Application。 * 然后将自己的Application类,配置到AndroidManifest.xml中的meta-data节点中,name为"ASC_Game_Application" * @author xiaohei * */ public class ASCUnityContext extends UnityPlayerActivity{ public final static String CALLBACK_GAMEOBJECT_NAME = "(ascsdk_callback)"; //unity中接收回调通知的GameObject的名称 public final static String CALLBACK_INIT = "OnInitSuc"; //SDK初始化成功的回调方法名称和Unity中一致 public final static String CALLBACK_LOGIN = "OnLoginSuc"; //SDK登录成功的回调方法名称和Unity中一致 public final static String CALLBACK_SWITCH_LOGIN = "OnSwitchLogin"; //SDK切换帐号的回调方法名称和Unity中一致 public final static String CALLBACK_LOGOUT = "OnLogout"; //SDK登出的回调方法名称和Unity中一致 public final static String CALLBACK_PAY = "OnPaySuc"; //SDK支付成功回调方法名称和Unity中一致 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initSDK(); } private void initSDK(){ ASCPlatform.getInstance().init(this, new ASCInitListener() { @Override public void onSwitchAccount(UToken data) { //游戏中通过SDK切换到新账号的回调,游戏收到该回调,需要引导用户重新登录,重新加载该新用户对应的角色数据 if(data == null){ tip("切换帐号失败,请重试"); return; } sendLoginResult(data, true); } @Override public void onPayResult(int code, String msg) { Log.d("ASCSDK", "pay result. code:"+code+";msg:"+msg); /*switch(code){ case ASCCode.CODE_PAY_SUCCESS: //tip("支付成功"); break; case ASCCode.CODE_PAY_FAIL: //tip("支付失败"); break; case ASCCode.CODE_PAY_CANCEL: //tip("支付取消"); break; case ASCCode.CODE_PAY_UNKNOWN: //tip("支付失败,未知错误"); break; }*/ } @Override public void onLogout() { //用户登出回调(需要收到该回调需要返回游戏登录界面,并调用login接口,打开SDK登录界面) sendCallback(ASCUnityContext.CALLBACK_LOGOUT, null); } @Override public void onLoginResult(int code, UToken data) { switch(code){ case ASCCode.CODE_LOGIN_SUCCESS: sendLoginResult(data, false); tip("登录成功"); break; case ASCCode.CODE_LOGIN_FAIL: tip("登录失败"); break; } } @Override public void onInitResult(int code, String msg) { Log.d("ASCSDK", "init result.code:"+code+";msg:"+msg); switch(code){ case ASCCode.CODE_INIT_SUCCESS: sendCallback(CALLBACK_INIT, null); tip("初始化成功"); break; case ASCCode.CODE_INIT_FAIL: tip("初始化失败"); break; } } @Override public void onProductQueryResult(List<ProductQueryResult> result) { // TODO Auto-generated method stub } @Override public void onVideoResult(int code, String msg) { // TODO Auto-generated method stub Log.d("ASCSDK", "onVideoResult result:"+msg); Toast.makeText(ASCUnityContext.this, "视频回调成功", Toast.LENGTH_LONG).show(); } @Override public void onSinglePayResult(int code, ASCOrder order) { Log.d("ASCSDK", "onSinglePayResult result:"+order.getProductID()); JSONObject json = new JSONObject(); String pId = ""; pId = order.getProductID(); try{ if(code == ASCCode.CODE_PAY_SUCCESS){ json.put("payResult", 0); }else{ json.put("payResult", 1); } json.put("productId", pId); }catch(Exception e){ e.printStackTrace(); } sendCallback(ASCUnityContext.CALLBACK_PAY,json.toString()); } @Override public void onDestroy() { // TODO Auto-generated method stub } }); } public void sendLoginResult(UToken authResult, boolean isSwitchAccount) { JSONObject json = new JSONObject(); try{ json.put("isSuc", authResult.isSuc()); json.put("isSwitchAccount", isSwitchAccount); if(authResult.isSuc()){ json.put("userID", authResult.getUserID()); json.put("sdkUserID", authResult.getSdkUserID()); json.put("username", authResult.getUsername()); json.put("sdkUsername", authResult.getSdkUsername()); json.put("token", authResult.getToken()); } }catch(Exception e){ e.printStackTrace(); } this.sendCallback(ASCUnityContext.CALLBACK_LOGIN, json.toString()); } public void nativeLog(String msg){ Log.d("ASC_LOG_UNITY", msg); } //登录接口 public void login(){ ASCPlatform.getInstance().login(this); } //显示用户中心接口 public void showAccountCenter(){ ASCPlatform.getInstance().showAccountCenter(); } //登出 public void logout(){ ASCPlatform.getInstance().logout(); } //提交扩展数据 public void submitExtraData(String data){ final UserExtraData extraData = parseGameData(data); ASCPlatform.getInstance().submitExtraData(extraData); } //SDK退出接口 public void exit(){ ASCPlatform.getInstance().exitSDK(new ASCExitListener() { @Override public void onGameExit() { //游戏自己的退出确认框 AlertDialog.Builder builder = new AlertDialog.Builder(ASCUnityContext.this); builder.setTitle("退出确认"); builder.setMessage("现在还早,要不要再玩一会?"); builder.setCancelable(true); builder.setPositiveButton("好吧", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { //这里什么都不用做 } }); builder.setNeutralButton("一会再玩", new DialogInterface.OnClickListener() { @SuppressLint("NewApi") public void onClick(DialogInterface dialog, int whichButton) { //退出游戏 ASCUnityContext.this.finish(); System.exit(0); } }); builder.show(); } }); } //支付接口 public void pay(String data){ final PayParams params = parsePayParams(data); ASCPlatform.getInstance().pay(this, params); } //SDK是否支持用户中心 public boolean isSupportAccountCenter(){ return ASCUser.getInstance().isSupport("showAccountCenter"); } //SDK是否支持退出确认框 public boolean isSupportExit(){ return ASCUser.getInstance().isSupport("exit"); } //SDK是否支持退出确认框 public boolean isSupportLogout(){ return ASCUser.getInstance().isSupport("logout"); } public boolean isSDKShowSplash(){ return ASCSDK.getInstance().isSDKShowSplash(); } //向Unity中发送消息 public void sendCallback(String name, String jsonParams){ if(jsonParams == null){ jsonParams = ""; } UnityPlayer.UnitySendMessage(CALLBACK_GAMEOBJECT_NAME, name, jsonParams); } private UserExtraData parseGameData(String str){ UserExtraData data = new UserExtraData(); try { JSONObject json = new JSONObject(str); data.setDataType(json.getInt("dataType")); data.setRoleID(json.getString("roleID")); data.setRoleName(json.getString("roleName")); data.setRoleLevel(json.getString("roleLevel")); data.setServerID(json.getInt("serverID")); data.setServerName(json.getString("serverName")); data.setMoneyNum(json.getInt("moneyNum")); String roleCreateTime = json.getString("roleCreateTime"); String roleLevelUpTime = json.getString("roleLevelUpTime"); if(!TextUtils.isEmpty(roleCreateTime.trim())){ data.setRoleCreateTime(Long.valueOf(roleCreateTime.trim())); } if(!TextUtils.isEmpty(roleLevelUpTime.trim())){ data.setRoleLevelUpTime(Long.valueOf(roleLevelUpTime.trim())); } data.setVip(json.optString("vip", "0")); } catch (JSONException e) { e.printStackTrace(); } return data; } private PayParams parsePayParams(String str){ PayParams params = new PayParams(); try{ JSONObject json = new JSONObject(str); params.setProductId(json.getString("productId")); params.setProductName(json.getString("productName")); params.setProductDesc(json.getString("productDesc")); params.setPrice(json.getInt("price")); params.setRatio(0);//该字段废弃不用 params.setBuyNum(json.getInt("buyNum")); params.setCoinNum(json.getInt("coinNum")); params.setServerId(json.getString("serverId")); params.setServerName(json.getString("serverName")); params.setRoleId(json.getString("roleId")); params.setRoleName(json.getString("roleName")); params.setRoleLevel(json.getInt("roleLevel")); params.setPayNotifyUrl(json.getString("payNotifyUrl")); params.setVip(json.getString("vip")); params.setExtension(json.getString("extension")); }catch(Exception e){ e.printStackTrace(); } return params; } public void onActivityResult(int requestCode, int resultCode, Intent data){ ASCSDK.getInstance().onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data); } public void onStart(){ ASCSDK.getInstance().onStart(); super.onStart(); } public void onPause(){ ASCSDK.getInstance().onPause(); super.onPause(); } public void onResume(){ ASCSDK.getInstance().onResume(); super.onResume(); } public void onNewIntent(Intent newIntent){ ASCSDK.getInstance().onNewIntent(newIntent); super.onNewIntent(newIntent); } public void onStop(){ ASCSDK.getInstance().onStop(); super.onStop(); } public void onDestroy(){ ASCSDK.getInstance().onDestroy(); super.onDestroy(); } public void onRestart(){ ASCSDK.getInstance().onRestart(); super.onRestart(); } private void tip(final String tip){ ASCSDK.getInstance().runOnMainThread(new Runnable() { @Override public void run() { //Toast.makeText(ASCUnityContext.this, tip, Toast.LENGTH_SHORT).show(); } }); } private void OnRate(){ try { String str = "market://details?id=" + ASCSDK.getInstance().getApplication().getPackageName(); Log.d("ASCSDK", "OnRate url:"+str); Intent localIntent = new Intent(Intent.ACTION_VIEW); localIntent.setData(Uri.parse(str)); ASCSDK.getInstance().getContext().startActivity(localIntent); } catch (Exception e) { // 打开应用商店失败 可能是没有手机没有安装应用市场 e.printStackTrace(); Toast.makeText(ASCSDK.getInstance().getContext().getApplicationContext(), "打开应用商店失败", Toast.LENGTH_SHORT).show(); // 调用系统浏览器进入商城 String url = "http://app.mi.com/detail/163525?ref=search"; openLinkBySystem(url); } } private void openLinkBySystem(String url) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); ASCSDK.getInstance().getContext().startActivity(intent); } } 

说明:

  • 其中,CALLBACK_GAMEOBJECT_NAME就是Unity中这个负责接收回调通知的GameObject的名称
  • 此类包含了初始化SDK,登陆,登出,退出,支付,提交扩展数据方法。
  • ASCInitListener此接口为所有回调的监听接口。

    • onPayResult------支付回调(网游专用接口)。
    • onLoginResult------登陆结果回调。
    • onInitResult------初始化结果回调。
    • onSinglePayResult------单机支付结果回调。
    • 还有一些登出,查询订单,视频回调等,详情看代码注解。

2. Untiy接入文档------Unity端

  • 拷贝上面Android端生成的ascsdk_unitylib.jar到unity工程libs目录中。
  • 拷贝ASCSDK的抽象层工程中的bin目录下生成的ascsdk3.jar拷贝到libs目录中。
  • 在Unity中怎么来完成Android中相关接口的调用以及封装。

    • 我们定义一个ASCSDKInterface的抽象单例类:
public abstract class ASCSDKInterface{ public delegate void LoginSucHandler(ASCLoginResult data); public delegate void LogoutHandler(); private static ASCSDKInterface _instance; public LoginSucHandler OnLoginSuc; public LogoutHandler OnLogout; public static ASCSDKInterface 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(ASCExtraGameData data); //调用SDK的退出确认框,返回false,说明SDK不支持退出确认框,游戏需要使用自己的退出确认框 public abstract bool SDKExit(); //调用SDK支付界面 public abstract void Pay(ASCPayParams data); //SDK是否支持退出确认框 public abstract bool IsSupportExit(); //SDK是否支持用户中心 public abstract bool IsSupportAccountCenter(); //SDK是否支持登出 public abstract bool IsSupportLogout(); //去ASCServer获取游戏订单号,这里逻辑是访问游戏服务器,然后游戏服务器去ASCServer获取订单号 //并返回 public ASCPayParams reqOrder(ASCPayParams data) { //TODO 去游戏服务器获取订单号 //测试 data.orderID = "345435634534"; data.extension = "test"; return data; } }
  • 有了这个抽象类,对于各个平台,我们需要分别实现该抽象类中的接口,从而间接地调用平台中的方法。对于Android平台,我们定义一个SDKInterfaceAndroid类:
public class SDKInterfaceAndroid : ASCSDKInterface { 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(ASCExtraGameData data) { string json = encodeGameData(data); SDKCall("submitExtraData", json); } public override bool SDKExit() { if (!IsSupportExit()) { //return false; } SDKCall("exit"); return true; } public override void Pay(ASCPayParams 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(ASCExtraGameData 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(ASCPayParams 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); } } 
  • 接下来,我们就定义一个专门负责回调的脚本:
public class ASCSDKCallback : MonoBehaviour { private static ASCSDKCallback _instance; private static object _lock = new object(); //初始化回调对象 public static ASCSDKCallback InitCallback() { UnityEngine.Debug.LogError("Callback->InitCallback"); lock (_lock) { if (_instance == null) { GameObject callback = GameObject.Find("(ascsdk_callback)"); if (callback == null) { callback = new GameObject("(ascsdk_callback)"); UnityEngine.Object.DontDestroyOnLoad(_instance); _instance = callback.AddComponent<ASCSDKCallback>(); } else { _instance = callback.GetComponent<ASCSDKCallback>(); } } return _instance; } } //初始化成功回调 public void OnInitSuc() { //一般不需要处理 UnityEngine.Debug.LogError("Callback->OnInitSuc"); } //登录成功回调 public void OnLoginSuc(string jsonData) { UnityEngine.Debug.LogError("Callback->OnLoginSuc"); ASCLoginResult data = parseLoginResult(jsonData); if (data == null) { UnityEngine.Debug.LogError("The data parse error." + jsonData); return; } if (ASCSDKInterface.Instance.OnLoginSuc != null) { ASCSDKInterface.Instance.OnLoginSuc.Invoke(data); } } //切换帐号回调 public void OnSwitchLogin() { UnityEngine.Debug.LogError("Callback->OnSwitchLogin"); if (ASCSDKInterface.Instance.OnLogout != null) { ASCSDKInterface.Instance.OnLogout.Invoke(); } } //登出回调 public void OnLogout() { UnityEngine.Debug.LogError("Callback->OnLogout"); if (ASCSDKInterface.Instance.OnLogout != null) { ASCSDKInterface.Instance.OnLogout.Invoke(); } } //支付回调,网游不需要实现该接口,该接口用于单机游戏 public void OnPaySuc(string jsonData) { //Nothing... } private ASCLoginResult parseLoginResult(string str) { object jsonParsed = MiniJSON.Json.Deserialize(str); if (jsonParsed != null) { Dictionary<string, object> jsonMap = jsonParsed as Dictionary<string, object>; ASCLoginResult data = new ASCLoginResult(); 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; } } 
  • 到这里,ASCSDK在Unity中的封装基本就算完成了,接下来,我们就来测试下接口的调用。我们用UGUI建立一个建立一个简单的面板,然后包含一个登录按钮和支付按钮,然后通过绑定一个ClickObject.cs脚本来简体按钮的响应事件:
public class ClickObject : MonoBehaviour { // Use this for initialization private Text txtState; void Start () { ASCSDKCallback.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>(); ASCSDKInterface.Instance.OnLoginSuc = delegate(ASCLoginResult result) { OnLoginSuc(result); }; ASCSDKInterface.Instance.OnLogout = delegate() { OnLogout(); }; } void Update() { if (Input.GetKeyUp(KeyCode.Escape)) { if (!ASCSDKInterface.Instance.SDKExit()) { //TODO 退出确认框 Application.Quit(); } } } void OnLoginSuc(ASCLoginResult 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() { ASCSDKInterface.Instance.Login(); } void OnPayClick() { ASCPayParams data = new ASCPayParams(); 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 = "asc_24532452"; data.roleName = "麻利麻利吼"; data.roleLevel = 15; data.vip = "v15"; data = ASCSDKInterface.Instance.reqOrder(data); ASCSDKInterface.Instance.Pay(data); } } 
  • 最后说明:
    我们将提供unity的工程的demo,具体可以参考我们demo,此文档暂时没有提供广告接口的说明,原理与login支付一样,调用我给你们提供的方法就可以,具体以我们给的demo为准。有任何问题可以联系我们的商务人员。
原文链接:https://yq.aliyun.com/articles/583807
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章