zoukankan      html  css  js  c++  java
  • 教你高速高效接入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篇)


  • 相关阅读:
    简单布局2
    面试问题之操作系统:Linux下进程的内存结构
    面试问题之C++语言:说一说C++中四种cast转换
    面试问题之C++语言:说一下static关键字的作用
    面试问题之操作系统:动态链接库和静态链接库的区别
    面试问题之数据结构与算法:简述深度优先遍历和广度优先遍历
    面试问题之C++语言:C与C++的区别
    面试问题之C++语言:Overload、Override及Overwirte的区别
    面试问题之计算机网络:TCP三次握手四次挥手
    面试问题之计算机网络:TCP滑动窗口
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/6920548.html
Copyright © 2011-2022 走看看