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

U8SDK的设计之初,就是为了可以支持各种游戏引擎开发的游戏,而不不过Android的原生平台。眼下一大半的手游,都是採用Unity3D和Cocos2dx开发,那么这里,我们就先来一步步给大家演示,用Unity开发的游戏,怎样通过U8SDK来高速地完毕多家渠道SDK的接入。

Unity研发的手游,仅仅须要调用U8SDK抽象层就可以完毕多家渠道SDK的接入。而不须要在Unity中耦合各个渠道SDK,保证游戏层逻辑层的简单,以及SDK部分的绝对重用。

以下,我们看看,在Unity中调用U8SDK主要须要完毕的工作:

1、建立一个Androidproject,作为U8SDK和Unity平台通信的中间协调project

2、定义一致的通信数据类型,我们这里採用JSON格式

3、在Unity中,通过C#完毕一套统一的SDK调用接口。给逻辑层调用。同一时候多个平台(Android,IOS,PC等)的接口全然同样。

这一篇。我们就先来完毕第一步和第二步。

1,新建一个Androidproject,将IsLibrary设置为true。将该project作为库project,这样当你编译的时候,会在bin文件夹下产生一个jar包。而不是一个apk

2,设置依赖project为U8SDK2抽象层project,同一时候将Unity3D提供的Android的jar包,拷贝到该project的libs文件夹下

3、然后建立两个类,一个为U8UnityContext ,这个类继承UnityPlayerActivity 。也是游戏的启动Activity。

4、还有一个是IU8SDKListener 的实现类,主要实现一些SDK的回调方法

我们先来看看这两个类的实现。之后再来解释一些关键的东西:

public class U8UnityContext extends UnityPlayerActivity{

	public final static String CALLBACK_GAMEOBJECT_NAME = "(u8sdk_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();
	}

	//U8SDK 初始化
	public void initSDK(){
		U8SDK.getInstance().setSDKListener(new UnityU8SDKListener(this));
		U8SDK.getInstance().init(this);
		U8SDK.getInstance().onCreate();
	}

	//登录接口
	public void login(){
		U8SDK.getInstance().runOnMainThread(new Runnable() {

			@Override
			public void run() {

				U8User.getInstance().login();
			}
		});
	}

	//自己定义登录接口
	public void loginCustom(final String customData){
		U8SDK.getInstance().runOnMainThread(new Runnable() {

			@Override
			public void run() {

				U8User.getInstance().login(customData);
			}
		});
	}

	//切换帐号接口
	public void switchLogin(){
		U8SDK.getInstance().runOnMainThread(new Runnable() {

			@Override
			public void run() {

				U8User.getInstance().switchLogin();
			}
		});
	}

	//显示用户中心接口
	public void showAccountCenter(){
		U8SDK.getInstance().runOnMainThread(new Runnable() {

			@Override
			public void run() {

				U8User.getInstance().showAccountCenter();
			}
		});
	}

	//登出
	public void logout(){
		U8SDK.getInstance().runOnMainThread(new Runnable() {

			@Override
			public void run() {

				U8User.getInstance().logout();
			}
		});
	}	

	//提交扩展数据
	public void submitExtraData(String data){
		final UserExtraData extraData = parseGameData(data);
		U8SDK.getInstance().runOnMainThread(new Runnable() {

			@Override
			public void run() {

				U8User.getInstance().submitExtraData(extraData);
			}
		});
	}

	//SDK退出接口
	public void exit(){
		U8SDK.getInstance().runOnMainThread(new Runnable() {

			@Override
			public void run() {

				U8User.getInstance().exit();
			}
		});
	}	

	//支付接口
	public void pay(String data){
		final PayParams params = parsePayParams(data);
		U8SDK.getInstance().runOnMainThread(new Runnable() {

			@Override
			public void run() {

				U8Pay.getInstance().pay(params);
			}
		});
	}

	//SDK是否支持退出确认功能
	public boolean isSupportExit(){

		return U8User.getInstance().isSupport("exit");
	}

	//SDK是否支持用户中心
	public boolean isSupportAccountCenter(){

		return U8User.getInstance().isSupport("showAccountCenter");
	}

	//SDK是否支持登出
	public boolean isSupportLogout(){

		return U8User.getInstance().isSupport("logout");
	}

	//向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"));
		} 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("");//该字段废弃不用
			params.setVip(json.getString("vip"));
			params.setOrderID(json.getString("orderID"));
			params.setExtension(json.getString("extension"));

		}catch(Exception e){
			e.printStackTrace();
		}

		return params;
	}

	public void onActivityResult(int requestCode, int resultCode, Intent data){
		U8SDK.getInstance().onActivityResult(requestCode, resultCode, data);
		super.onActivityResult(requestCode, resultCode, data);
	}

	public void onStart(){
		U8SDK.getInstance().onStart();
		super.onStart();
	}

	public void onPause(){
		U8SDK.getInstance().onPause();
		super.onPause();
	}
	public void onResume(){
		U8SDK.getInstance().onResume();
		super.onResume();
	}
	public void onNewIntent(Intent newIntent){
		U8SDK.getInstance().onNewIntent(newIntent);
		super.onNewIntent(newIntent);
	}
	public void onStop(){
		U8SDK.getInstance().onStop();
		super.onStop();
	}
	public void onDestroy(){
		U8SDK.getInstance().onDestroy();
		super.onDestroy();
	}
	public void onRestart(){
		U8SDK.getInstance().onRestart();
		super.onRestart();
	}

}
public class UnityU8SDKListener implements IU8SDKListener{

	private U8UnityContext context;

	private boolean isSwitchAccount = false;		//当前是否为切换帐号

	public UnityU8SDKListener(U8UnityContext context){
		this.context = context;
	}

	@Override
	public void onResult(final int code, String msg) {
		// TODO Auto-generated method stub
		U8SDK.getInstance().runOnMainThread(new Runnable() {

			@Override
			public void run() {
				switch(code){
				case U8Code.CODE_INIT_SUCCESS:
					context.sendCallback(U8UnityContext.CALLBACK_INIT, null);
					break;
				case U8Code.CODE_INIT_FAIL:
					Toast.makeText(context, "SDK初始化失败", Toast.LENGTH_SHORT).show();
					break;
				case U8Code.CODE_LOGIN_FAIL:
					//这里不须要提示。一般SDK有提示
					//Toast.makeText(context, "SDK登录失败", Toast.LENGTH_SHORT).show();
					break;
				case U8Code.CODE_PAY_FAIL:
					Toast.makeText(context, "支付失败", Toast.LENGTH_SHORT).show();
					break;
				case U8Code.CODE_PAY_SUCCESS:
					Toast.makeText(context, "支付成功,到账时间可能稍有延迟", Toast.LENGTH_SHORT).show();
					break;
				}
			}
		});
	}

	//此接口已经废弃
	@Override
	public void onInitResult(InitResult result) {
		// TODO Auto-generated method stub
		// 此接口已经废弃
	}

	//SDK登录成功的回调
	@Override
	public void onLoginResult(String data) {
		Log.d("U8SDK", "SDK 登录成功,不用做处理,在onAuthResult中处理登录成功, 參数例如以下:");
		Log.d("U8SDK", data);
		this.isSwitchAccount = false;
		tip("SDK登录成功");
	}

	//切换帐号。须要回到登录界面,并弹出SDK登录界面
	@Override
	public void onSwitchAccount() {
		context.sendCallback(U8UnityContext.CALLBACK_SWITCH_LOGIN, null);	

	}

	//切换帐号,并登录成功。到这里和Login的回调onLoginResult一样
	@Override
	public void onSwitchAccount(String data) {
		Log.d("U8SDK", "SDK 切换帐号并登录成功,不用做处理。在onAuthResult中处理登录成功, 參数例如以下:");
		Log.d("U8SDK", data);
		this.isSwitchAccount = true;		

		tip("切换帐号成功");
	}

	//登出,须要回到登录界面,并弹出SDK登录界面
	@Override
	public void onLogout() {
		context.sendCallback(U8UnityContext.CALLBACK_LOGOUT, null);
	}

	//SDK登录成功之后。去U8Server进行登录认证
	@Override
	public void onAuthResult(UToken authResult) {

		if(!authResult.isSuc()){
			tip("SDK登录认证失败,确认U8Server是否配置");
			return;
		}

		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();
		}

		context.sendCallback(U8UnityContext.CALLBACK_LOGIN, json.toString());
	}

	//对于手机网游,不须要实现这个接口,由于网游支付是通过server回调通知加虚拟币的。
	//这个接口主要用于单机游戏。作为单机的支付结果回调接口
	@Override
	public void onPayResult(PayResult result) {
		//TODO
	}

	private void tip(final String tip){
		U8SDK.getInstance().runOnMainThread(new Runnable() {

			@Override
			public void run() {
				Toast.makeText(context, tip, Toast.LENGTH_SHORT).show();
			}
		});
	}
}

在U8UnityContext 中,我们定义了一系列的接口。这些接口就是给Unity中调用的。

比方Login,switchLogin,logout等。而这些方法本身不过对U8SDK抽象层提供的方法进行了一个简单的包裹。通过,U8SDK.getInstance().runOnMainThread()来让全部的接口都在UI主线程中完毕。

关于U8SDK的初始化,有两部分。第一部分是U8SDK本身的初始化,包含參数的读取和解析等,这个须要将AndroidManifest.xml中application接口的android:name设置为”com.u8.sdk.U8Application”。注意,这里一定要设置,否则U8SDK无法初始化。假设,游戏有自己的某些业务须要在Application中完毕,能够通过实现U8SDK提供的IApplicationListener接口来完毕。

第二部分须要在Activity的onCreate中完毕(依据游戏不同,也能够在Unity中合适的地方调用初始化接口),包含,设置U8SDK的回调监听,初始化载入插件,以及调用onCreate回调。表现为下面三步:

U8SDK. getInstance().setSDKListener (new UnityU8SDKListener(this));

U8SDK. getInstance().init(this);

U8SDK. getInstance().onCreate();

UnityU8SDKListener 是U8SDK的回调简体接口的实现类。全部SDK相关的回调都是通过这些接口完毕的。

onLoginResult:     SDK登录成功的回调

onSwitchAccount:   SDK中切换帐号的回调

onLogout:          SDK登出的回调

onAuthResult:      U8Server登录验证的回调

onResult:          全部SDK操作成功或者失败的状态回调

当我们收到部分回调的时候,我们须要通知到Unity中,包含之前。我们写的那些接口,比方Pay和submitExtraData都是含有參数的。

这里就来解决Unity和Android中通信的数据结构问题。尽管Unity和Android通信也能够使用复杂的结构,可是我还是推荐採用简单统一的数据协议比較好。这里我们选择JSON。简单高效。仅仅要保证。两边数据的key一致就能够了。

Unity调用Android的接口,比方Pay和submitExtraData都通过一个JSON字符串传递过来,然后这边解析一下。

对于Android中须要通知Unity中的也是一样,使用JSON格式的字符串,然后通过

UnityPlayer.UnitySendMessage(gameObject, methodName, jsonParams)接口来完毕通信。

好了,完毕这个,Android中的部分,就完毕了。再提醒一次,不要忘记配置AndroidManifest.xml哦,这里附上AndroidManifest.xml文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.u8.sdk"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name="com.u8.sdk.U8Application">

        <activity
            android:name="com.u8.sdk.U8UnityContext"
            android:label="@string/app_name"
            android:screenOrientation="landscape"
            android:launchMode="singleTask"
            android:configChanges="orientation|keyboardHidden|screenSize">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>            

        </activity>        

    </application>

</manifest>

接下来。我们就须要在Unity中来完毕接下来的工作,能够看訪问这里查看:Unity手游接入渠道SDK(Unity篇)

时间: 2024-10-10 23:29:03

教你高速高效接入SDK——Unity统一接入渠道SDK(Android篇)的相关文章

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

上一篇,我们着重讲解了用Unity开发的手游,在接入U8SDK时,Android中的部分.接下来,这一篇,我们就来看看,在Unity工程中,我们需要怎么调用上一篇中我们提供的各种接口,以及怎么接收Android中的消息通知,比如登录成功,切换帐号成功等. 在写代码之前,我们先要做一个简单的配置,在Project面板中,按照Unity官方的要求,新建一个Plugins文件夹,在Plugins文件夹下,再建立一个Android文件夹.这里,将会放置所有Android工程相关的文件. 1.将上一篇中,

高效率完成一次接入80个手游渠道SDK——游戏接入SDK客户端篇

一.引言 通常,游戏开发商并不会只在一个渠道上线他们的游戏,接入越多的渠道,代表着可能获取越多的用户,但同时也代表着越多的接入SDK工作量.工期和费用.一款游戏要有足够的用户,甚至需要接入30家以上的各种渠道,以保障自己的市场覆盖率.单个SDK接入流程在一位有经验的全职客户端程序.一位全职服务端程序员.一位全职QA处理的情况下,需要3天时间才能完成.因此当一款产品面对30个甚至更多不同需求的渠道SDK时,人员成本和时间成本就会急剧增加. 所以我们需要一个通用接口,来处理各种渠道的需求,这就是统一

高效率完成一次接入80个手游渠道SDK——游戏接入SDK服务端篇

1 概要    通常,游戏开发商并不会只在一个渠道上线他们的游戏,接入越多的渠道,代表着可能获取越多的用户,但同时也代表着越多的接入SDK工作量.工期和费用.一款游戏要有足够的用户,甚至需要接入30家以上的各种渠道,以保障自己的市场覆盖率. 单个SDK接入流程在一位有经验的全职客户端程序.一位全职服务端程序员.一位全职QA处理的情况下,需要3天时间才能完成.因此当一款产品面对30个甚至更多不同需求的渠道SDK时,人员成本和时间成本就会急剧增加.所以我们需要一个通用接口,来处理各种渠道的需求,这就

手机游戏渠道SDK接入工具项目分享(三)拨开云雾是个坑

一直在纠结是先写框架设计还是先写掉过的坑,最后本这娱乐大众的态度先写掉过的坑让大家乐呵下. 项目开发过程中遇问题无数,回顾下8个大坑照成了项目一定程度上延期甚至返工. 1.  项目一开始几个人把现有3家主流的产品(1接,棱镜,AnySDK)研究了一遍.没想先在这里就进坑了.在研究了几天后发现这3家虽推出有一定时间,但都是以第三方服务角度设计和开发的产品,与需求不符. 2.  版本管理.和流程管理等内容因为运营人员更替一直在调整,直到我提出需要加价才做吧.需求上快把打包工具做成OA系统了,删除了于

教你快速高效接入SDK——渠道SDK的接入(就是实现抽象层的接口而已)

题记:很多做游戏开发的人,估计都或多或少地接过渠道SDK,什么UC,当乐,91,小米,360......据统计国内市场当前不下于100家渠道,还包括一些没有SDK的小渠道.每个渠道SDK接入的方法呢,多是大同小异.但是,正是这些小异,又让SDK的接入,产生了无穷无尽的变数.所以,接入SDK之前,如果你没有经验,或者没有被SDK坑过,那么当你看到这系列文章的时候,你很幸运,你可以避免这一切了.如果你之前被坑过,而且还在继续被坑着,那么现在,就是你解脱的时刻. 先将之前的每一篇做个索引,方便亲们查阅

NOSDK--关于android一键打包及统一接入国内多个平台SDK的想法与实现(前言)

前言 一,一键打包的实现 1.1 shell文件介绍 1.2 自动刷新mk文件 1.3 自动拷贝资源 1.4 使用ant实现打包 1.5 拷贝icon 二,统一接入多个平台 1.1 nosdk框架介绍 1.2 nosdk_library基本库介绍 1.3 游戏逻辑与sdk平台的分离 1.4 xx平台接入示例 三,后记 做SDK平台接入工作已经有一年多了,自认对于大多平台的sdk都基本熟悉了,因此计划写一个系列的文章,介绍自己对于一键打包及统一接入多个平台sdk的一些想法与实现,算是对于这一年多的

unity3d如何快速接入渠道SDK之Unity篇

首先我们讲一下,为什么要介绍这个插件? 是因为这个插件极大的简化了我对接渠道SDK的工作量,精力和时间,也避免了我不断的重复的做接入SDK工作这样没有成就感的无聊工作! 所以我就介绍一下这款插件!!!!!! 我的开发环境:windows系统 , eclipse , unity4.3.4 这款插件的工作方式是中间件加插件 这样的组合模式工作的. 所以需要先接入中间件. 对接过程: 1. 准备中间件工程对接(http://www.abctools.cn/documentCenter/toSdkDow

Unity3d Android SDK接入解析(四)通用的Android SDK接入中间件

一.前言 接入Android SDK正式告一段落,在这段时间里面,依次接入了华为.应用宝.小米.360等等大大小小十来个SDK,也算对Unity接入渠道SDK有了较为全面的理解,对各个渠道的坑也算深有体会....在接入过程中时间比较紧张,没办法抽空来进行总结深思.今天正好有空,便对之前的接入SDK的代码进行了一次重构,写了一个比较通用的Unity接入Android SDK的中间件,前人栽树,后人乘凉. 进入正题 如果有对一些只是有疑问的,可以看看我之前的三篇文章: 传送门: Unity3d An

手机游戏渠道SDK接入工具项目分享(二)万事开头难

一般接到任务后程序员们通常都开始着手进行技术调研了,但我这活是项目负责人.还有一大堆事情要先期准备,没人能帮忙. 一.人力配置 考虑的之前已经有一波人搞了大半年,但没有起色,先期也没有太大人力需求,所以不指望这批人了.因为是外包收钱按人头工时算,所以拉几个自己兄弟填坑. 初期人力配置 服务端x 1.Android x 1 二.开发需求 自己手机游戏CP作了3年,需求直接写完后让对方确认,一次通过. 1.      公司多款游戏都需要使用这套工具,需要作适配兼容,还好都是Unity3D项目.之后我