public class SDKInterfaceAndroid : U8SDKInterface
{
private AndroidJavaObject jo;
public SDKInterfaceAndroid()
{
using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
jo = jc.GetStatic("currentActivity");
}
}
private T SDKCall(string method, params object[] param)
{
try
{
return jo.Call(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("isSupportExit");
}
public override bool IsSupportAccountCenter()
{
return SDKCall("isSupportAccountCenter");
}
public override bool IsSupportLogout()
{
return SDKCall("isSupportLogout");
}
private string encodeGameData(U8ExtraGameData data)
{
Dictionary map = new Dictionary();
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 map = new Dictionary();
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();
}
else
{
_instance = callback.GetComponent();
}
}
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 jsonMap = jsonParsed as Dictionary;
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();
btnLogin.onClick.AddListener(delegate()
{
OnLoginClick();
});
GameObject payObj = GameObject.Find("BtnPay");
Button btnPay = payObj.GetComponent();
btnPay.onClick.AddListener(delegate()
{
OnPayClick();
});
GameObject stateObj = GameObject.Find("TxtState");
txtState = stateObj.GetComponent();
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