Android/Unity大乱斗-完整双方集成交互指南
这是一个很长很长的story!-芝麻粒儿创作
开篇
源码地址:GitHub
本文目的,将Unity集成到Android端,学完本文后你可以做到
- Android任意布局加载Unity 3D场景
- 任意操作布局中的按钮/3D物品(缩放旋转等)
- 互相消息通信(你叼我,我叼你)
- 自由切换Unity中的场景
- 动态加载手机SD卡3D资源,一次开发到处使用。
- 在小白面前装逼用

故事正题
首要任务就是将Unity项目导出来(已经做好了3D的处理,关于通信和动态加载在下面介绍)

敲黑板,重点Export Project一定要勾选,之后点击最下方的Export 静等项目导出。

导出后的结构感觉好熟悉,就跟Android Studio的项目结构一样(PS:本来就是)打开Studio 以 moudle的形式导入android工程,第一次可能慢一些慢慢导,去喝杯茶。成功后重要的操作来了。打开刚才导入的build.gradle文件,首当其冲的就是gradle版本的修改,跟你的studio版本一致。
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'
}
apply plugin: 'com.android.application'
改为
apply plugin: 'com.android.library'
因为我们要以library的形式集成,接着再往下面走就是熟悉的sdkVsersion了,保持和你的anroid项目一致。还有个applicationId,删掉这个。
有的项目遇见UnityAds.aar文件,不影响。其他修改以及遇到的一些坑不再赘述,有问题可以留言。我的如下:
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'
}
}
allprojects {
repositories {
google()
jcenter()
flatDir {
dirs 'libs'
}
}
}
apply plugin: 'com.android.library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
android {
compileSdkVersion 29
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
minSdkVersion 21
targetSdkVersion 29
ndk {
abiFilters 'armeabi-v7a', 'x86'
}
versionCode 1
versionName '1.0'
}
lintOptions {
abortOnError false
}
aaptOptions {
noCompress = ['.unity3d', '.ress', '.resource', '.obb']
}
buildTypes {
debug {
minifyEnabled false
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'
jniDebuggable true
}
release {
minifyEnabled false
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'
signingConfig signingConfigs.debug
}
}
packagingOptions {
doNotStrip '*/armeabi-v7a/*.so'
doNotStrip '*/x86/*.so'
}
}
接着打开Unity项目的清单文件AndroidManifest.xml,删减application节点,删除intent-filter节点,activity增加内容process(解决某某问题)
<application
//删减其他
android:banner="@drawable/app_banner"
android:isGame="true">
<activity
.....
//删除下面两行-否则造成桌面两个icon
//android:label="@string/app_name"
//android:launchMode="singleTask"
//增加这行
android:process="e.unity3d">
//删掉intent-filter
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN" />-->
<!--<category android:name="android.intent.category.LAUNCHER" />-->
<!--<category android:name="android.intent.category.LEANBACK_LAUNCHER" />-->
<!--</intent-filter>-->
<meta-data
android:name="unityplayer.UnityActivity"
android:value="true" />
</activity>
......
至此,配置完成,已经可以玩了。
但为了玩的顺畅,我们再增加一个自定义控件(1.用来解决kill问题 2.增强自己的扩展性)。自定义一个java文件集成UnityPlayer(核心关键类)

public class MUnityPlayer extends UnityPlayer {
public MUnityPlayer(Context context) {
super(context);
}
@Override
protected void kill() {
//super.kill();
//unity默认一些返回操作等会直接kill掉进程,覆写kill方法,去掉super.kill, 不让他kill
}
}
配置完成,点击菜单栏的Build,Rebuild Project unity的lib项目中生成aar文件


Unity导出的项目配置完成,配置自己的Android项目,首先将几个lib......so复制到你自己的项目jniLibs中。
然后在你需要集成的项目build文件中
implementation(name: 'XingFeiUnity', ext: 'aar')
一波骚操作搞定,跑起来已经基本可以了。但是这就结束了吗?不可能,骚起来我们就停不下来。
布局渲染
我们需要在任意布局加载3d,怎么个任意法?就是找个view来addview 既不影响3d 还有android原生界面
//xml布局
<LinearLayout
android:id="@+id/linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="50dp"
android:orientation="vertical" /> //java文件
mLinear.removeAllViews();
mLinear.addView(mUnityPlayer.getView());
mUnityPlayer.requestFocus();
操作效果请看图片,全部具体代码的话 就直接放到Github了

通信交互
Android调用Unity
//参数二是 Unity中的方法名 参数一是哪个物体挂在了这个C#脚本 参数三 字符串
UnityPlayer.UnitySendMessage("Main Camera", "AndroidCallUnity", "");

Unity调用Android 仔细看注释
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class Manager : MonoBehaviour
{
private AndroidJavaObject m_androidObj = null;
public GameObject diqiu; void Start()
{
//注意-情况不同 com.unity3d.player.UnityPlayer 可能不同,可参考其他博主
AndroidJavaClass androidClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
m_androidObj = androidClass.GetStatic<AndroidJavaObject>("currentActivity");
diqiu.SetActive(false);
} //Unity中的某个物体出发此事件
public void UnityCallAndroid()
{
Debug.Log("调用方法");
if (m_androidObj != null)
{
Debug.Log("调用方法进来");
// 第一个参数是android里面java代码的方法名,第二个是携带的字符串参数
m_androidObj.Call("CallAndroid", "我是Unity,我给你发消息了");
}
} //Android调用Unity-方法名一定要注意
public void AndroidCallUnity(string json)
{
if (diqiu.activeInHierarchy)
{
diqiu.SetActive(false);
}
else
{
diqiu.SetActive(true);
}
}
}
场景切换
- Unity内部自己去处理,就跟玩游戏一样,让Unity开发自己去做
- andorid触发,unity换场景,这个借助上面说的消息通信来实现
- 这还有一个技巧,如果资源不是很多且在一个场景的话,可以让Unity一次直接渲染出来存在字典里,然后想显示哪个Android给Unity发消息,Unity根据订好的消息,展示不同的内容,这个好处就是切换展示速度极快。重点处理一下刚启动的时候的耗时即可。
动态资源
态加载资源的问题,因篇幅有限,咱先只提供个思路,Unity支持读取android设备的存储文件,让他们处理即可,然后android发消息告诉他们地址即可
// 参数一是Unity中的物体名称,参数二Unity中的方法名 参数三路径字符串
UnityPlayer.UnitySendMessage("AndriodMethodMgr", "CallUnitySetPath", Environment.getExternalStorageDirectory() + "");
啊哈,到这基本就结束了。快了又开心。
坑中带坑
为了愉快的装逼,最好还是看一看遇到的这些问题,能至少省几天时间。
1. 混淆问题,如果你开启了混淆,切记 切记,把混淆添加进入,这个大坑耽误我好久啊
2. 如果模型在unity中没问题,在android端穿帮,可以看看发布质量,将android的设置成高的

3. 如果反复执行的模型动画不对,怎么不对?举例心脏跳动,这是非常注重动画的衔接的,如果衔接时间不对会造成心脏动画的抖动,这会非常的明显。
可以看动画的setting 退出时间,退出时间是比例(如下图),1代表全部动画,0.5代表动画使劲按的一般。过度时间前后动画重叠(好像默认.95?) 可以改成0,如图设置

4. 集成到apk后 申请了横竖屏 但是apk没作用,是unity发布出的设置导致的,再Unity导出的时候 other setting中设置宣传方向
5. 权限问题,上面说了会导出一个android项目,你仔细看这个项目的AndroidManifest文件,你会发现也有权限。
注意,这时候比如你的android项目有权限A 这个Unity导出的项目没有权限A,当你集成合并之后,导致最终的apk没有权限A,这并不是我们想看到的;
所以为了 解决这个问题,很简单,我们把两个清单文件的权限保持一致即可,记住啊,否则怎么哭的都不知道。
6. 还有一个未解决的问题,放到这,有朋友知道的话,感谢指教。
带有动画的一个物体,在有的android设备上,动画表现征程,但是有的会出现动画跳动的情况,感觉像是电视的进度条那在跳进度一样。
结尾
最后,别问我为啥知道这么多问题,问就是因为自己跪着走过来的。

Android/Unity大乱斗-完整双方集成交互指南的更多相关文章
- GridView的 PreRender事件与 RowCreated、RowDataBound事件大乱斗
GridView的 PreRender事件与 RowCreated.RowDataBound事件大乱斗 之前写了几个范例,做了GridView的 PreRender事件与 RowCreated.Row ...
- python红蓝英雄大乱斗(面向对象实现)
红蓝英雄大乱斗 游戏规则 ''' 有红蓝两方英雄(可自定义个数) 随机一方英雄使用随机攻击方式攻击另一方英雄,任意一方英雄全部阵亡则游戏结束 每个英雄有 名字.生命值.普通攻击.Q技能攻击.W技能攻击 ...
- Cocos Creator | 飞刀大乱斗开发教程系列(三)
预览效果 具体内容 ■ 这一期,主要讲解游戏过程中,通过触摸滑动,控制人物的运动方向,以及游戏过程中,人物运动区域的控制.如下图,人物通过滑动控制运动方向,即是往哪个方向滑动,人物就往哪个方向移动 ...
- 【追寻javascript高手之路03】javascript对象大乱斗
前言 昨天我们学习了下javascript中函数的参数与作用域的东东,现在回过头来看,其实都是与函数相关的,所以javascript中的函数仍然是王道,我们今天大概会发二篇或者三篇博客一起来巩固我们的 ...
- Cocos Creator | 飞刀大乱斗开发教程系列(一)
预览效果 具体内容 ■ 这一期,主要讲解主页下方列表选项如何实现.也就是游戏开始后,加载所有现有的英雄列表,这一功能的实现,如下图部分. ■ 列表使用 ScrollView 实现,横向滚动,设置好上下 ...
- Cocos Creator | 飞刀大乱斗开发教程系列(二)
预览效果 具体内容 ■ 这一期,主要讲解主页中间人物效果的实现.也就是,在下方列表选择不同人物,上方显示不同的人物,播放不同的效果,即下图的效果实现,此部分也是采用预制 Prefab 进行实现. 英雄 ...
- 浏览器编年史与UserAgent大乱斗
1993 世界上第一个支持显示图片的浏览器Mosaic诞生 为了区分浏览器是否能显示图片,UserAgent诞生了,Mosaic将自己标志为NCSA_Mosaic/2.0(windows 3.1) 1 ...
- Java 单例模式大乱斗
1. 饿汉模式 线程安全 public class SingleInstance1 { private static SingleInstance1 single=new SingleInstance ...
- 使用 CocoStudio UI 编辑器实现《乱斗堂》设置界面
由于是引用别人的,所以直接贴上地址了.http://www.cocoachina.com/bbs/read.php?tid=164820&fpage=7 1 游戏中必不可少的 UI 元素 ...
随机推荐
- iptables [-t table] 指定规则表
-t 参数用来,内建的规则表有三个,分别是:nat.mangle 和 filter,当未指定规则表时,则一律视为是 filter.个规则表的功能如下: nat:此规则表拥有 PREROUTING 和 ...
- 用diiv实现多个方块居中嵌套--padding
文章地址 https://www.cnblogs.com/sandraryan/ 案例:用diiv嵌套多个正方形,配合盒模型相关知识,使每个div在他的父元素上居中.(每个div中心点对齐) 涉及到m ...
- 理解java面向对象基础
1. 类和对象 一切皆对象,这可以说是面向对象的核心思想了. 类,就是具有相同性质对象的抽象. 而类的每一个具体的实例就是一个对象. 我们可以定义一个Person类,这个Person类就是所有的人的抽 ...
- dotnet 设计规范 · 结构体定义
X 不要给结构体默认构造函数 默认的C#编译器也不让开发者定义有默认构造的结构体 X 不要定义易变的属性 易变的属性指的是在调用属性返回值的时候返回的是新的实例,易变的属性会有很多的问题. ✓ 需要确 ...
- Python--day46--用户管理设计方案介绍
1,基于用户权限管理: 2,基于角色的权限管理: 开始一个项目如果要100天的,可能70天都在设计,比如设计数据库表结构,最后30天才是写代码.设计是最难的,写代码是最简单的. 还有一个重要的一点,写 ...
- Xshell + SVN使用
切换目录 cd+想跳转到的目录下 文件浏览 ls ll (ll 信息全) svn更新 svn up 编辑 vi vi的命令 文件保存与退出: :q 在文件未作任何修改的情况下退出. :q! 强制退出, ...
- 【p083】传球游戏
Time Limit: 1 second Memory Limit: 50 MB [问题描述] 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样 ...
- 开源项目使用 appveyor 自动构建
我写了几个开源项目,我想要有小伙伴提交的时候自动运行单元测试,自动运行编译,这样可以保证小伙伴提交清真的代码 本文将会告诉大家如何接入 appveyor 自动构建方案,在 Github 上给自己的开源 ...
- Vue基础练习之计算属性、方法、监听器
<body> <div id="root"> {{fullName()}} {{age}} </div> <script> var ...
- 【t068】智慧碑
Time Limit: 1 second Memory Limit: 128 MB [问题描述] DIABLO魔王和Mini都有三种属性,体力点,攻击点,以及集气点. 两人的攻击方式是这样的:采用回合 ...