【Unity游戏开发】SDK接入与集成——小白入门篇

1、简介

  一般一款游戏开发到后期,通常都会涉及到第三方SDK的接入与集成,对于不熟悉SDK接入的同窗来讲,接SDK每次都是云里雾里,而熟悉SDK接入的同窗又以为不断地重复作接入SDK工做这样没有成就感,太尼玛无聊了(Android渠道一弄就十几个,直接吐血)。其实一般状况下接入SDK都是很简单的一个过程,本系列博客就让马三和你们从小白开始,从零基础开始学习如何接入SDK以及一些常见的SDK的接入流程。本系列博客规划为如下几篇:html

  • SDK接入与集成——小白入门篇(介绍环境搭建以及Unity和Android的基本交互与调用)
  • SDK接入与集成——信鸽SDK篇(介绍消息推送框架--信鸽SDK的接入)
  • SDK接入与集成——QQ与微信SDK篇(都是腾讯开放平台的,就放在一块儿学了)
  • SDK接入与集成——科大讯飞SDK篇(游戏中的语音通讯和语音识别会用到此SDK)
  • SDK接入与集成——百度地图SDK篇(作LBS游戏必不可少)
  • SDK接入与集成——第三方SDK接入解决方案AnySDK篇
  • SDK接入与集成——构建本身的Android集成多SDK框架篇

  先挖了这么多坑,之后慢慢填吧,放心博主确定不会太监的。java

2、浅谈经常使用的两种接入方案

1.第三方SDK接入解决方案

  其实游戏SDK接入发展到如今,已经有不少成熟的第三方SDK接入解决方案了,好比AnySDK,ShareSDK,U8SDK等等。这些第三方SDK接入解决方案的整个接入过程,不改变任何SDK的功能、特性、参数等,对于最终玩家而言是彻底透明无感知的。让CP商能有更多时间更专一于游戏自己的品质。第三方SDK包括了渠道SDK、用户系统、支付系统、广告系统、统计系统、分享系统等等。利用他们能够轻松快速接入第三方SDK。android

  第三方SDK的统一验证流程基本以下:git

  

2.手动接入SDK

  既然上面说的第三方解决方案那么好,为何咱们还有手动去接入SDK呢?造轮子就这么上瘾?其实接入了一些第三方的SDK解决方案之后,咱们有的游戏数据是要通过他们的服务器的,对于一些游戏厂商来讲,不想让本身的数据通过别人的服务器,或者须要对验证服务器有彻底自主的控制权,那么必然要手动接入各类SDK了。另外还有一些奇奇怪怪,很是诡异的SDK,咱们也是要手动去接入的,不能都期望第三方的集成。并且做为一名合格的猿类来讲,知其然更要知其因此然,掌握SDK的接入原理和过程颇有必要。github

3、开始接入!Unity与Android的交互

  前面啰嗦了那麽多,到这里终于能够开始实战操做了。服务器

1.Android开发环境搭建

  关于Android环境的搭建,网上已经有不少博客了,介绍的很详细,马三就不在这里水了。这里给你们安利一个关于Android开发工具的好网站:http://www.androiddevtools.cn/ 。上面提供了不少可用的AndroidADK国内镜像和教程。微信

2.Android端的开发工做

  (1)打开IDE创建一个空的Android库工程,这里我用Eclispe举例。注意Min Required SDK最好选择4.0以上,要否则还须要引入android-support-v7兼容包,比较麻烦,以后咱们能够把这个Min Required SDK 再该回来的。须要注意的两步已经截图了,剩下一路Next操做便可。注意包名和勾选Mark this project as a library选项。app

  

  (2)导入Classes.jar包到Android工程中框架

  Unity和Android作交互,他们两个之间不认识确定,无法直接通讯,所以须要一个中间的搭桥牵线的人,Classes.jar就起到了这个做用。Classes.jar是由Unity提供给咱们的,咱们须要找到它而且引入到咱们的Android项目中。Claess.jar的路径通常以下 X盘:\xxx目录\Unity\Editor\Data\PlaybackEngines\androidplayer\release\bin\classes.jar(不一样的计算机上,这个位置可能会有所不一样,你们按照本身的路径添加便可)。咱们找到它直接拖到咱们的Android工程的libs目录下。而后在它上面右键,将其添加到Build Path中。编辑器

  

  添加到Build Path成功之后,工程是这个样子的。

  

  (3)编写Android端的代码

  咱们在Android端编写一些代码,提供一些接口来供Unity一会的调用。打开咱们的MainActivity.java,而后添加代码。须要注意的是,让咱们的MainActivity继承Jar包中的UnityPlayerActivity类,这样,Unity才能调的到哦,缺什么包,直接让Eclipe自动导下包便可,快捷键ctrl+shift+o。对了,还须要把 setContentView(R.layout.activity_main); 这段代码注释掉,要否则会显示Android的默认布局文件,上面就一个 Hello World。

  

 

  简单的写了几个普通方法和一个静态方法,供一会的测试调用。(不管是静态方法仍是普通方法,在Unity中都是能够调用的到的)MainActicity.java的代码内容以下:

 1 package com.mx.sdkbase;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.view.Menu;
 6 import android.view.MenuItem;
 7 import android.widget.Toast;
 8 
 9 import com.unity3d.player.UnityPlayer;
10 import com.unity3d.player.UnityPlayerActivity;
11 
12 public class MainActivity extends UnityPlayerActivity {
13 
14     private static MainActivity instance;
15 
16     @Override
17     protected void onCreate(Bundle savedInstanceState) {
18         super.onCreate(savedInstanceState);
19         // setContentView(R.layout.activity_main);
20 
21         instance = this;
22     }
23 
24     @Override
25     public boolean onCreateOptionsMenu(Menu menu) {
26         // Inflate the menu; this adds items to the action bar if it is present.
27         getMenuInflater().inflate(R.menu.main, menu);
28         return true;
29     }
30 
31     @Override
32     public boolean onOptionsItemSelected(MenuItem item) {
33         // Handle action bar item clicks here. The action bar will
34         // automatically handle clicks on the Home/Up button, so long
35         // as you specify a parent activity in AndroidManifest.xml.
36         int id = item.getItemId();
37         if (id == R.id.action_settings) {
38             return true;
39         }
40         return super.onOptionsItemSelected(item);
41     }
42 
43     
44     /**
45      * 供Unity调用的求和函数
46      * @param x
47      * @param y
48      * @return
49      */
50     public int Sum(int x, int y) {
51         return x + y;
52     }
53 
54     /**供Unity调用的比较最大值函数
55      * @param x
56      * @param y
57      * @return
58      */
59     public int Max(int x, int y) {
60         return Math.max(x, y);
61     }
62 
63     
64     /**供Unity调用的显示吐司的函数
65      * @param str
66      */
67     public void MakeToast(String str) {
68         Toast.makeText(this, str, Toast.LENGTH_LONG).show();
69     }
70 
71     
72     /**供Unity调用的自加一函数
73      * @param x
74      * @return
75      */
76     public int AddOne(int x) {
77         return x + 1;
78     }
79 
80     
81     /**供Unity调用的静态方法,单例类,返回当前的Activity对象
82      * @return
83      */
84     public static MainActivity GetInstance() {
85         return instance;
86     }
87     
88     
89     /**供Unity调用的函数,此函数会回调指定的一个Unity中的方法,完成数据的双向交互
90      * @param str
91      */
92     public void CallUnityFunc(String str){
93         str=str+"Android Call Unity.";
94         String ReceiveObject="MessageHandler";
95         String ReceiverMethod="Receive";
96         UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str);
97     }
98 }

 

   (4)导出咱们的Android项目为Jar包供Unity调用

  在咱们的项目上面右键,而后选择Export,选择Java目录下的 Jar file。由于没有用到第三方的jar包或者lib库,所以只要勾选src/和res/目录导出为jar包便可。

  

  (5)Unity端工程的开发

  创建一个新的空Unity工程,而后在Asset/目录下创建以下路径的文件夹:Plugins/Android。从名字就能够看出来,这个文件夹是用来存放安卓的插件的。而后将咱们上面刚刚导出的SDKBase.jar 包导入到这个目录下,而且将Andoird工程目录下的,libs/ 、res/ 、AndroidMainFest.xml 都复制到该路径下。

  须要特别注意的是要将Unity 项目中 libs下的classes.jar文件删除掉,这个就是上面提到的那个起到中介做用的jar包,必定要删掉!必定要删掉!必定要删掉!(重要的事情说三遍,网上很多教程都是针对Unity老版的教程,没有提到要删除这个classes.jar包,结果在Unity 5.x中打包确定会出错)。出错截图以下所示。

   

  而后咱们创建一个场景,简单地在里面放上一些Label和输入框、按钮,供咱们验证交互操做。而且编写一个脚本(MessageHandler.cs便是我建立的脚本), 在其中编写用来调用Jar包的C#方法,而后将按钮和这些函数绑定(Unity基本操做,不赘述了)。

   

  MessageHandler.cs 脚本的内容以下,函数的功能看注释就好了,写得很全。

 1 using System;
 2 using UnityEngine;
 3 using UnityEngine.UI;
 4 
 5 public class MessageHandler : MonoBehaviour
 6 {
 7     private AndroidJavaClass _jc;
 8     private AndroidJavaObject _jo;
 9 
10     public InputField inputFieldA;
11     public InputField inputFiledB;
12     public Text resultLabel;
13 
14     // Use this for initialization
15     void Start()
16     {
17         //初始化
18         //"com.unity3d.player.UnityPlayer"和"currentActivity"这两个参数都是固定的
19         //UnityPlayerActivity里面对其进行了处理
20         _jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
21         _jo = _jc.GetStatic<AndroidJavaObject>("currentActivity");
22     }
23 
24     public void AddOne()
25     {
26         int a = Convert.ToInt32(inputFieldA.text);
27 
28         //注意,这里使用的就不是以前默认的com.unity3d.player.UnityPlayer,而是须要传入本身的类(实现了须要调用相应方法的类)
29         //由于默认的UnityPlayer中是没有咱们所须要的方法的,因此须要加载本身的类
30         AndroidJavaClass jc = new AndroidJavaClass("com.mx.sdkbase.MainActivity");
31         //调用Java中的静态方法,单例模式,返回当前Activity实例
32         AndroidJavaObject jo = jc.CallStatic<AndroidJavaObject>("GetInstance");
33         resultLabel.text = "AddOne" + jo.Call<int>("AddOne",a);
34     }
35 
36     public void Sum()
37     {
38         int a = Convert.ToInt32(inputFieldA.text);
39         int b = Convert.ToInt32(inputFiledB.text);
40         //调用Java类中的普通方法,返回值为int型
41         resultLabel.text = "Sum: " + _jo.Call<int>("Sum", a, b);
42     }
43 
44     public void Max()
45     {
46         int a = Convert.ToInt32(inputFieldA.text);
47         int b = Convert.ToInt32(inputFiledB.text);
48         resultLabel.text = "Max: " + _jo.Call<int>("Max", a, b);
49     }
50 
51     public void CallUnityFunc()
52     {
53         //调用Java中的一个方法,该方法会回调Unity中的指定的一个方法,这里会回调Receive( )
54         _jo.Call("CallUnityFunc","Unity Call Android.\n");
55     }
56 
57     public void Receive(string str)
58     {
59         resultLabel.text = str;
60     }
61 
62     public void Toast()
63     {
64         _jo.Call("MakeToast","Unity 调用Toast");
65     }
66 }

 

  经过上面的代码,咱们就能够看出来,想在Unity中调用Android的代码,主要涉及到了两个类。AndroidJavaClass 和 AndroidJavaObject 。这两个类在Unity API手册里面有详细的解释。

  下面的代码是获取到对应包名的java.lang.Class实例,这里获取到的是com.unity3d.player.UnityPlayer类。

_jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

  下面的代码是获取到UnityPlayer类中的静态字段,它的返回值类型是AndroidJavaObject对象。

_jo = _jc.GetStatic<AndroidJavaObject>("currentActivity");

  经过以上两行代码,咱们能够获取到这个AndroidJavaObject 对象,而后用 AndroidJavaObject 对象就能够任意地调用Android中的静态和非静态函数了。其中两个函数中的字符串参数 "com.unity3d.player.UnityPlayer" 和 "currentActivity" 都是固定的写法,咱们不用去改变。

  AndroidJavaObject 类的一些经常使用方法及功能以下表所示:

AndroidJavaObject 构造函数,根据类名返回AndroidJavaObject对象
Call 调用Android代码中的非静态方法
CallStatic 调用Android代码中的静态方法
Dispose IDisposable 回调
Get 获取Android代码中的非静态字段
GetRawClass 获取一个指向Java class的原始引用
GetRawObject 获取一个指向Java object的原始引用
GetStatic 获取Android代码中的静态字段
Set 设置Android代码中的非静态字段
SetStatic 设置Android代码中的静态字段

 

  另外,咱们还有第二种方法去访问Java的代码,那就是利用咱们以前在Java代码中写的 GetInstance() 静态方法,它会返回一个MainActivity的实例,咱们拿到这个实例之后,就能访问里面的方法和字段了。须要注意的是此时的AndroidJavaClass构造函数中传递的字符串就不是 "com.unity3d.player.UnityPlayer" 了。而是要传入本身的包名,好比代码中的 “com.mx.sdkbase.MainActivity” 。代码以下:

        int a = Convert.ToInt32(inputFieldA.text);

        //注意,这里使用的就不是以前默认的com.unity3d.player.UnityPlayer,而是须要传入本身的类(实现了须要调用相应方法的类)
        //由于默认的UnityPlayer中是没有咱们所须要的方法的,因此须要加载本身的类
        AndroidJavaClass jc = new AndroidJavaClass("com.mx.sdkbase.MainActivity");
        //调用Java中的静态方法,单例模式,返回当前Activity实例
        AndroidJavaObject jo = jc.CallStatic<AndroidJavaObject>("GetInstance");
        resultLabel.text = "AddOne" + jo.Call<int>("AddOne",a);

  不止Unity能够调用Android的代码,Android也能够反过来回调Unity的代码。下面这段代码就是用来回调Unity函数的:

    /**供Unity调用的函数,此函数会回调指定的一个Unity中的方法,完成数据的双向交互
     * @param str
     */
    public void CallUnityFunc(String str){
        str=str+"Android Call Unity.";
        String ReceiveObject="MessageHandler";
        String ReceiverMethod="Receive";
        UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str);
    }

  利用UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str); 就能够返回过来回调一个Unity中的方法,完成Unity和Android的双向通讯。其中第一个参数是接受该回调的gameobject名称,第二个参数是挂载在该gameobject上面的一个脚本中接受该消息的方法,最后一个参数是本条消息发送的字符串信息。好比上面例子中的代码就会调用名称为MessageHandler的gameobject上面挂载的脚本中的Receive方法。

  (6)打包发布Android平台的APK

  代码写好之后,咱们会习惯性地在Unity Editor 里面运行查看一下效果,可是若是要调用 Android 代码的话,是不能够这样作的,必定要在真机上运行(模拟器上也行),在Editor中运行会报错的。因此咱们仍是打包发布到Android端查看效果吧。

  在Unity中按快捷键 ctrl +b ,打开Build Setting界面,而后把平台切换为 Android 平台并将咱们的测试场景加到Build Setting队列中。点击PlayerSetting,对工程的信息进行配置。注意要把里面的Company Name和Product Name修改为和包名一致。以下图所示:

  

  而后 ,Bundle Identifier的值也要修改为和包名同样,而且调整下Minimum API Level。以下图:

  

  最后,还记得咱们在最一开始创建Android库工程的时候,将最小安装需求的API调成了4.0吗,这就意味着,打出来的APK包安装运行的最低系统要求是Android 4.0。这样确定是不能够的,要考虑到低版本的Android系统。所以还须要作最后一步的修改,才能打包。

找到咱们Unity项目中的 AndroidManifest.xml 文件,用文本编辑器打开它,将android:minSdkVersion的值修改为上一步在面板中设置的 Minimum API Level 对应的版本号,好比我这里面的  Minimum API Level 为2.3.3,其版本号为 10。

  

  以后,咱们就能够放心地打包了,打包成功后安装到手机上测试下效果,下面是我在模拟器上测试的几张效果图:

    

   

  能够看到Unity成功地调用到了Android中的方法,并返回正确的结果,并且Android反过来也回调了Unity中的方法。

4、结语

  关于“SDK接入与集成的小白入门篇”就写到这里了,经过本篇博客,咱们一块儿初步地了解和学习了一下Unity和Android是如何交互的。下篇博客,咱们将会实战地练习一下“消息推送框架”信鸽SDK的接入与使用,敬请期待!

  最后放上本篇博客中演示的项目源码:

  Github地址:https://github.com/XINCGer/Unity3DTraining/tree/master/SDK/SDKBase    欢迎fork!

 

 

做者:马三小伙儿
出处:http://www.cnblogs.com/msxh/p/7220741.html 请尊重别人的劳动成果,让分享成为一种美德,欢迎转载。另外,文章在表述和代码方面若有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论!

相关文章
相关标签/搜索