当前位置: 代码迷 >> Android >> 教你高速高效接入SDK——Unity统一接入渠道SDK(Android篇)
  详细解决方案

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

热度:111   发布时间:2016-04-27 23:43:52.0
教你快速高效接入SDK——Unity统一接入渠道SDK(Android篇)
U8SDK的设计之初,就是为了能够支持各种游戏引擎开发的游戏,而不仅仅是Android的原生平台。目前一大半的手游,都是采用Unity3D和Cocos2dx开发,那么这里,我们就先来一步步给大家演示,用Unity开发的游戏,如何通过U8SDK来快速地完成多家渠道SDK的接入。
 
Unity研发的手游,只需要调用U8SDK抽象层即可完成多家渠道SDK的接入,而不需要在Unity中耦合各个渠道SDK,保证游戏层逻辑层的简单,以及SDK部分的绝对重用。
 
下面,我们看看,在Unity中调用U8SDK主要需要完成的工作:
 
1、建立一个Android工程,作为U8SDK和Unity平台通信的中间协调工程
2、定义一致的通信数据类型,我们这里采用JSON格式
3、在Unity中,通过C#完成一套统一的SDK调用接口,给逻辑层调用。同时多个平台(Android,IOS,PC等)的接口完全相同。
 
这一篇,我们就先来完成第一步和第二步。
 
1,新建一个Android工程,将IsLibrary设置为true,将该工程作为库工程,这样当你编译的时候,会在bin目录下产生一个jar包,而不是一个apk
2,设置依赖工程为U8SDK2抽象层工程,同时将Unity3D提供的Android的jar包,复制到该工程的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());	}		//对于手机网游,不需要实现这个接口,因为网游支付是通过服务器回调通知加虚拟币的。	//这个接口主要用于单机游戏,作为单机的支付结果回调接口	@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篇)


版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案