【Unity游戏开发】SDK接入与集成——小白入门篇
一、简介
通常一款游戏开发到后期,一般都会涉及到第三方SDK的接入与集成,对于不熟悉SDK接入的同学来说,接SDK每次都是云里雾里,而熟悉SDK接入的同学又觉得不断地重复做接入SDK工作这样没有成就感,太尼玛无聊了(Android渠道一弄就十几个,直接吐血)。其实通常情况下接入SDK都是很简单的一个过程,本系列博客就让马三和大家从小白开始,从零基础开始学习如何接入SDK以及一些常见的SDK的接入流程。本系列博客规划为以下几篇:
- SDK接入与集成——小白入门篇(介绍环境搭建以及Unity和Android的基本交互与调用)
- SDK接入与集成——信鸽SDK篇(介绍消息推送框架--信鸽SDK的接入)
- SDK接入与集成——QQ与微信SDK篇(都是腾讯开放平台的,就放在一起学了)
- SDK接入与集成——科大讯飞SDK篇(游戏中的语音通信和语音识别会用到此SDK)
- SDK接入与集成——百度地图SDK篇(做LBS游戏必不可少)
- SDK接入与集成——第三方SDK接入解决方案AnySDK篇
- SDK接入与集成——构建自己的Android集成多SDK框架篇
先挖了这么多坑,以后慢慢填吧,放心博主肯定不会太监的。
二、浅谈常用的两种接入方案
1.第三方SDK接入解决方案
其实游戏SDK接入发展到现在,已经有很多成熟的第三方SDK接入解决方案了,比如AnySDK,ShareSDK,U8SDK等等。这些第三方SDK接入解决方案的整个接入过程,不改变任何SDK的功能、特性、参数等,对于最终玩家而言是完全透明无感知的。让CP商能有更多时间更专注于游戏本身的品质。第三方SDK包括了渠道SDK、用户系统、支付系统、广告系统、统计系统、分享系统等等。利用他们可以轻松快速接入第三方SDK。
第三方SDK的统一验证流程基本如下:
2.手动接入SDK
既然上面说的第三方解决方案那么好,为什么我们还有手动去接入SDK呢?造轮子就这么上瘾?其实接入了一些第三方的SDK解决方案以后,我们有的游戏数据是要经过他们的服务器的,对于一些游戏厂商来说,不想让自己的数据经过别人的服务器,或者需要对验证服务器有完全自主的控制权,那么必然要手动接入各种SDK了。另外还有一些奇奇怪怪,非常诡异的SDK,我们也是要手动去接入的,不能都指望第三方的集成。而且作为一名合格的猿类来说,知其然更要知其所以然,掌握SDK的接入原理和过程很有必要。
三、开始接入!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选项。
(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的代码内容如下:
package com.mx.sdkbase; import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast; import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity; public class MainActivity extends UnityPlayerActivity { private static MainActivity instance; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main); instance = this;
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
} /**
* 供Unity调用的求和函数
* @param x
* @param y
* @return
*/
public int Sum(int x, int y) {
return x + y;
} /**供Unity调用的比较最大值函数
* @param x
* @param y
* @return
*/
public int Max(int x, int y) {
return Math.max(x, y);
} /**供Unity调用的显示吐司的函数
* @param str
*/
public void MakeToast(String str) {
Toast.makeText(this, str, Toast.LENGTH_LONG).show();
} /**供Unity调用的自加一函数
* @param x
* @return
*/
public int AddOne(int x) {
return x + 1;
} /**供Unity调用的静态方法,单例类,返回当前的Activity对象
* @return
*/
public static MainActivity GetInstance() {
return instance;
} /**供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);
}
}
(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 脚本的内容如下,函数的功能看注释就行了,写得很全。
using System;
using UnityEngine;
using UnityEngine.UI; public class MessageHandler : MonoBehaviour
{
private AndroidJavaClass _jc;
private AndroidJavaObject _jo; public InputField inputFieldA;
public InputField inputFiledB;
public Text resultLabel; // Use this for initialization
void Start()
{
//初始化
//"com.unity3d.player.UnityPlayer"和"currentActivity"这两个参数都是固定的
//UnityPlayerActivity里面对其进行了处理
_jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
_jo = _jc.GetStatic<AndroidJavaObject>("currentActivity");
} public void AddOne()
{
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);
} public void Sum()
{
int a = Convert.ToInt32(inputFieldA.text);
int b = Convert.ToInt32(inputFiledB.text);
//调用Java类中的普通方法,返回值为int型
resultLabel.text = "Sum: " + _jo.Call<int>("Sum", a, b);
} public void Max()
{
int a = Convert.ToInt32(inputFieldA.text);
int b = Convert.ToInt32(inputFiledB.text);
resultLabel.text = "Max: " + _jo.Call<int>("Max", a, b);
} public void CallUnityFunc()
{
//调用Java中的一个方法,该方法会回调Unity中的指定的一个方法,这里会回调Receive( )
_jo.Call("CallUnityFunc","Unity Call Android.\n");
} public void Receive(string str)
{
resultLabel.text = str;
} public void Toast()
{
_jo.Call("MakeToast","Unity 调用Toast");
}
}
通过上面的代码,我们就可以看出来,想在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中的方法。
四、结语
关于“SDK接入与集成的小白入门篇”就写到这里了,通过本篇博客,我们一起初步地了解和学习了一下Unity和Android是如何交互的。下篇博客,我们将会实战地练习一下“消息推送框架”信鸽SDK的接入与使用,敬请期待!
最后放上本篇博客中演示的项目源码:
Github地址:https://github.com/XINCGer/Unity3DTraining/tree/master/SDK/SDKBase 欢迎fork!
作者:马三小伙儿
出处:http://www.cnblogs.com/msxh/p/7220741.html
请尊重别人的劳动成果,让分享成为一种美德,欢迎转载。另外,文章在表述和代码方面如有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论!
【Unity游戏开发】SDK接入与集成——小白入门篇的更多相关文章
- 【Unity游戏开发】接入UWA_GOT的iOS版SDK以后无法正常出包
一.正文 问: RT,最近有看到UWA_GOT工具新增了iOS版本的支持,于是下载了最新的工具包进行了接入测试.是按照文档直接将UWA_GOTv2.0.1_iOS.unitypackage导入进了Un ...
- 【Unity游戏开发】不接SDK也能在游戏内拉起加QQ群操作?
一.引子 一般在游戏进行对外测试的时候都会有一个玩家QQ群,方便玩家反馈问题.交流游戏心得等.那么为了增加玩家加QQ群的欲望,可能会在游戏里面设计一个小功能,点击一下可以直接拉起手Q加群的操作,加了Q ...
- 手机游戏渠道SDK接入工具项目分享(三)拨开云雾是个坑
一直在纠结是先写框架设计还是先写掉过的坑,最后本这娱乐大众的态度先写掉过的坑让大家乐呵下. 项目开发过程中遇问题无数,回顾下8个大坑照成了项目一定程度上延期甚至返工. 项目一开始几个人把现有3家主流的 ...
- 手机游戏渠道SDK接入工具项目分享(二)万事开头难
一般接到任务后程序员们通常都开始着手进行技术调研了,但我这活是项目负责人.还有一大堆事情要先期准备,没人能帮忙. 一.人力配置 考虑的之前已经有一波人搞了大半年,但没有起色,先期也没有太大人力需求,所 ...
- 2017年Unity游戏开发视频教程(入门到精通)
本文是我发布的一个Unity游戏开发的学习目录,以后我会持续发布一系列的游戏开发教程,都会更新在这个页面上,适合人群有下面的几种: 想要做独立游戏的人 想要找游戏开发相关工作的人 对游戏开发感兴趣的人 ...
- 手机游戏渠道SDK接入工具项目分享(一)缘起
#剧情章节 # 上周刚结束一个外包的项目,开发手机游戏渠道SDK聚合接入工具的,现在有空回顾整理一下这个项目开发过程,因涉嫌商业秘密不会提供项目代码,只谈下开发思路和掉过的坑. 本人多年从事手机互联网 ...
- 【Unity游戏开发】浅谈Lua和C#中的闭包
一.前言 目前在Unity游戏开发中,比较流行的两种语言就是Lua和C#.通常的做法是:C#做些核心的功能和接口供Lua调用,Lua主要做些UI模块和一些业务逻辑.这样既能在保持一定的游戏运行效率的同 ...
- 【Unity游戏开发】用C#和Lua实现Unity中的事件分发机制EventDispatcher
一.简介 最近马三换了一家大公司工作,公司制度规范了一些,因此平时的业余时间多了不少.但是人却懒了下来,最近这一个月都没怎么研究新技术,博客写得也是拖拖拉拉,周六周天就躺尸在家看帖子.看小说,要么就是 ...
- 关于Unity游戏开发方向找工作方面的一些个人看法
这是个老生常谈,却又是谁绕不过去的话题,而对于每个人来说,所遇到的情况又不尽相同,别人的求职方式和路线不一定适合你,即使是背景很相似的两个人,有时候机遇也很重要. 我本人的工作经验只有一年,就业方式 ...
随机推荐
- springMVC+Mybatis(使用AbstractRoutingDataSource实现多数据源切换时)事务管理未生效的解决办法
业务场景: A.B两个单位,系统部署同一套代码: A.B两系统能相互访问: 要求将数据从A系统同步到B系统,再将反馈信息回发给A: 实际开发情况: 因为系统比较小,最开始设计架构的时候没有考虑到消息互 ...
- Blend在WPF开发过程中的作用
WPF开发时,用VS2012就足够了,因为里面的确有控件拖放编辑和便利的带输入自动完成的xaml编辑器. 但是在需要改变某些控件的样式时,特别是style和template是,看网上搜到的教程,洋洋洒 ...
- 提高java编程质量 - (一)易变业务使用脚本语言编写
脚本语言的3大特征: 1.灵活:脚本语言一般是动态类型,可以不声明变量类型直接使用,也可以在运行期改变类型:2.便捷:脚本语言是解释性语言,在运行期变更非常方便,而不用重启服务3.简单:脚本语言语法比 ...
- Unslider Web前端框架之图片轮播
前端框架,前端组件,前端库,都是一个意思,能看源码. 最近做H5小游戏,用到了图片轮播的组件,而且要求支持移动端触屏滑动.一开始用的是nivo slider,但是对大小不一样的图不支持box 的参数设 ...
- vue初学实践之路——vue简单日历组件(1)
---恢复内容开始--- 最近做的项目有一个需求,需要有一个日历组件供预定功能使用,之前的代码过于繁琐复杂,所以我采用vue重写了这个组件. npm.vue等等安装. 只是一个简单的日历组件,所以并不 ...
- 安装npm及cnpm(Windows)
[工具官网] Node.js : http://nodejs.cn/ 淘宝NPM: https://npm.taobao.org/ [安装步骤] 一.安装node.js 1.前往node.js官网下载 ...
- Perl正则表达式例子
Perl正则表达式 一.介绍 正则表达式各语言都有自己的规范,但是基本都差不多,都是由元字符的组合来进行匹配:由于Nmap内嵌的服务与版本探测是使用的Perl正则规范,因此此篇博客记录一下Perl正则 ...
- Java注解--实现简单读取excel
实现工具类 利用注解实现简单的excel数据读取,利用注解对类的属性和excel中的表头映射,使用Apache的poi就不用在业务代码中涉及row,rows这些属性了. 定义注解: @Retentio ...
- 常用html标签的只读写法
<a href="baidu.com" onclick="event.returnValue=false;">百度</a> a链接的只读 ...
- 9.session的生命周期
1.创建 当客户端第一次访问某个jsp或者Servlet的时候,服务器会为当前会话创建一个SessionId,每次客户端向服务端发送请求的时候,都会将此SessionId携带过去,服务端会对此Sess ...