Unity3D和移动端(Android)交互

Unity3D本身就是一款跨平台开发软件,兼容性高,但是往往在开发移动端过程中,需要与Android原生态进行混合开发,这就包括两中形式:

  • 以Unity3D为主导开发
  • 以Android为主导开发
  1. Unity3D为主导,调用Android! Q $ ; A原生态代- w * 1 p Z } W ?
    (1)首先我们使用AndroidStudio创建一个普通的Android工程,注意要记着PackageName的名称;

    注意:I 6 u如果工程格式不对,要打开app目录下) 0 h的build.gradle文件,将apply plugin: 'comx * V ~ L O 6 .android.application',改成apply plugin: 'com.android.library',因为android studiu w _ Co只有在这种格式下才可以导出unity需要使用的aar或者jar文件。然后删除defaultConfig下的applic# e ~ ) 1ationId,去掉默认的dependencies下的
    compile E p T j ] P X x'com.android.support:appcompat-v7:25.0.0'的引入,因为这里不需要用到它,而且这个包包含了很多的资源文件3 x E q # X 7 R我们是C : K $ n用不到的,最后格式为。

(2)从unity安装目录的Editor0 / C Q g h\Data\PlaybackEngines. a 7 k # p r l jAndroidPlayer\Variations\mono\Release\Cy 0 Blasses中,复制classes.jar出来,放到该刚才建的工程的libs文件夹里,并右键add as library
Unity3D和移动端(Android)交互
Unity3D和移动端(Android)交互
(3)修改AndroidManifest.xml

首先删除value] ) = N w 9 $s下的style.xml文件,因为这里面默认包含的是之前删除的com.android.support:appcompat-v7:25.0.0包里面的主题。然后修改AndroidManifest文件中application下的theme为android自带的主题。同时将<activity android:name=".MainActivity">修改为<activity android:name="cn.unity.android.MainActivityS d K j">,防止在unity中导出的app与AndroidManif- Q ~ | 0 P 9 ? kes8 M n k Qt中的包名不一致产生的问题。p a )然后添加<meta-data>信息,否则在 Unity 导出 APK 时会报找不到manifest 文件的错误信息

 <meta-data android:name="unityplayer.UnityActivity" androi= + R V ] . x hd:value="tru? g c E 3 L v u 9e" /> 

最终如下:
Unity3D和移动端(Android)交互
(4)上安卓原生代码

package com.romantic.forunity;
import an6 ^ P w ` g T 7droid.{ e u !app.AlertDialog;
import android.os.Vibrator;
import android.F - Wos.+ i { q S ? Y * {Bundle;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;
impot S /rt com.unity3d.player.UnityPlayerActiK C W Yvity% j F O i 5;
public class MainActivity extends Unit2 Y 8 U ! B ^ z 6yPlayerActivity {
@Override
protected void onCreate(Bundle savedInstanceStat} O / ^ E q Me) {
super.onCreate(savedInstanceState);
}
public String ShowDialog(final String _tB # { 2 @itle, final String _coK x antex u b p 4 4nt){
runOnUiThread(new Runnable() {
@Override
public void run() {
Alere F T .tDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
bY t #uilS h ! Oder.setTitle(_titl3 I L o }e).set6 ~ ^ z CMessage(_content).setPositiveButton("Down* v f ] H", null);
builder.show(# B * F 0);
}
});
return "Java return";
}
// 定义一个显示Toast的方法,在Unity8 r ` M @ @ K (中调用此方法
public void ShowToast(final String mStr2Show){
// 同样需要在UI线程下执行
ru^ 0 _ c [ R FnOnUiThread(new RG D V D M k Hunnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),mStr2Show, Toast.LENGTH_LONG)%  _ y m ? r V B.show();
}
});
}
}

(5)导出aar包和jar包

点击build-->build apk,然后在app-->build-->outputs-->aar目录下的到app-debug.aar文件| f R C
将app-debug.a j + { ~ # J , xaar文件解压,得到根目录下的classes.jar文件,请注H X , E , I . H +意这个classes.jar文件并不是最开始从unity中导入到android的classes.jar文件,而且你写的android代码的c5 D . m @ v 2 ) 2lass文件的压缩包(可以解压看看里面实际的内容)。之后unity所需要使用的是res文件夹下的文件,classf f g E / je# ? _ t ss.jar(android的)和AndroidManifest文件。
Unity3D和移动端(Android)交互

(6)Unity3D上面需要的工作

然后将我们之前导出的jar和res文件拷贝到Plugins/Android文件夹下。

直接上代码

 //获取An0 e Sdroid的Java接口
AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.j F n ~ 3player.UniR ? ityPlayer");
jo = jc.GetStatic<AndroidJavaObject> ("c1 y ? q 1 / ! :urrentAc_ , tivity");
//每个unity app在启动的时候都会有一个unityPlayer实例。通过获取该实例里面currentActivity对象,其实就是我们/ _ U w的MainActivity实例。
py S y 2 gublic void  ShowAndroidTime ()
{
jo.Call ("showToast", "Test" });
}

同样安卓也可调用Unity中的方法(在安i : 0 * - - 8 t卓原生态脚本中添加):

   // 第一个参数是unity中的对象名字,记住是对象名字,不是脚本类名
// 第二个参数是函数名
// 第三l ? V - } A m | )个参数是传给函数的参数,目前只看到一个参数,并且是string的,自己传进去转吧
ps @ U t v 1 oublic void callUnityFunc(String _objName , String _funcStr, String _content)
{
UnityPlayer.UnitySendMessage(] y h X S v W N __objName, _funcStr, "Come from:" + _content);
}

最后导出App就OK了。

  1. 以Android为主导开发,从U4 k y l z ) z Rnity 2019.3.a2开始,我们通过把Unity运行时组件和内容集成到原R x B ` p D J 6生平台C ? E 6 ? y ! { J项目,在原生应用中将Unity作为库使用

    注意:
    Unity版本必须是Unity 2019.3.a2以上
    Androu K ! U Zid Studio 3.3.2以上
    将Unity作为库使用,要求开发者对Android/Java和iOS/Objective C的架构有着深入的了解。
    由于Unit@ Y Ny不再控制运行时的生命周期,因此我们无法确保它可以在所有用例都正常工作

Unity运行时库会公开控制功能,以管理在原生应用中加载,激活和卸载的时间和方式。移 t ! } A f t `动应用的构建过程总体上依旧相同,Unity将创建Android Gradle项目。
为了启用该功能,我们修改= 7 { D C c z了生成iOS Xcode和Android Gradle项目的结构,结构如下:
1、F R M &库:Android Archive(AAR)文件,包含所有源文件和插件。
2、精简的启动器:包含应用程序展示数据,它会运行库部分。
如果使用Unity作为库,Android Gradle项目的结构I 0 o g会发生改变。如果使用自定义mainTempl( 5 kate.gradleH $ , i 9 (或AndroidMe [ p $ % Oanifest.xml,这些改变也会影响项目或Unity插件。


此前,Unity会使用单个Gradle模块来构建Android应用。现在,Unity会Y : X : C ` E }使用二个模块创建Gradle项目,即:unityLibrary模块和启动器模块。unityLibrary模块包含Unity运行时9 } l & C x % V Z和项目数据。` [ 8 5 :该模块是一个可以轻松集成到任何其它Gradle项目中的库,也可以把Unity嵌入到现有原生Android项目中。


启动器模块包含所有图标和应用名称,它是一个简单的Android应用程序,可以启动Unity。


将Unity作为库会提供新的Gradle项目结构,它会更好的符合Android Studio项目最佳结构。该结构中有一个根文c P x h S - ;件夹,其中包) . w ` o o } ^含一些可以单独构建和使用的子项目。它让导入Unity Android Studio项目更加简单。


Gradle模板会描述和配置使用Gradle构建Android应用的方法。每个Gr7 = 4 Wadle模板代表一个Gradle项目,Gradle项目可以包括和依赖其它Gradle项目。

将Unity作为库的Gradle模板文件如下:
1、baseP^ L Y ( Q 0 grojectTemplate.gradle:包含所有其它d w ^ t R G s模板和Gradb 1 | Q } | 2le项目共享的配置,即Android Gradle插件上的代码库和依赖。
2、launcherTemplate.gradleL ~ ?:包含如何构建Android应用的指令,例如:打包,签名和APK分离等,具体取决于unityLibrarF { % z 6 ?y项p R R目,它会输出一个APK文件或App Bundle。
3、mainTempl` j s Q jate.gradle:包含如何把Unf c p ] w _ q [ oity构建为库的指令,它会输出.aar格式文件,用户可以提供自定义模板来重写Unity模板,包括编辑器设置。
4、libTempl. ^ 0 ] K +ate.gradle:与之前的工作方式相同。

将Unity作为库会改变Unity Android应用清单文件的X k G使用方式。此前会有一个AndroidManifest.xml文件,用于给Android应i x m J / %用提供图标、行为、权限和其它设置。使用新系统后,我们有二个清单文件,! u e B O m而不是一个:| : W E 9

1m u [ n 8 B )、LauncherMani- G K , !fest.x9 F 0 t $ ) m x dml:负责处理图标、应用名称、开始行为及其目的、安装位置、支 a 6 e F ) x持的屏幕大小和设置“isGame”。
2、LibraryManiB - 3 % }fest.xml:负责声明Unity行为、权限、Unity行为使用的主题、VR模式、VR性能、使行j M ( 4 T u为不可以调整大小、设置最大高宽比、应对配置改动、朝向、启动模式、A| 5 E 1 x 8 3 v jndroid UI硬件加速、使用的功能,例如游戏手柄或图形API和槽口支持。该清单文件可以通过在Plugins/Android文件夹中提供自定义AndroidManifese [ j P ^ ! wt.xml文件来重写。

: B w a 2 ! d C1)下载gradle插件,进行Unity开发。
(2)Unity3D打包切换到安卓平台,选择导出项7 _ F Q ] Z }
Unity3D和移动端(Android)交互
将UnityProject导出到androidBuild文件夹,文件夹结构应如下所示:
Unity3D和移动端(Android)交互
(3)将Unity库模块添加到NativeAnZ d 1 j T 8 _ *droidApp,在Android Studio中打开NativeAndr= c 8 $ }oidApp,
打开settings.gradle,在settings.gradle5 f y 5 P C j 0 L文件的末尾,我们添加了指向unityLibrary模块的新项目:

包括':unitH F I U / H 8 ^ {yL f F . ^ & B % Vibrary'
项目(':unityLibraryM B K z { 4 e' )。projectDir =新文件('.. \\ UnityPy h q | 9 [ ) Z =rojectS D Q { y \\ androidBuild \\ unityLibrary' )

Unity3D和移动端(Android)交互
打开build.gradle(模块:应用),在依赖关系块中添加以下内容

实施项目(':unityLibrary' )

Unity3D和移动端(Android)交互
打开build.gradle(项目:NativeAndroidA! S y k ; S 4pp),在allprojects {repositories {块中添加以下内容

flatDir {
dirs “ $ {project(':unitO  @ C , Z W {yLibr1 6 = ~ ? X = ? Rary')。projectDir} / lib6 w T H B U f B ks”
}

Unity3D和移动端(Android)交互
后面就可以看见unityLibrary模块。j ( x 1
最后运行调试,打包就可以了。
附上官网专家解答地址:
https://forum.uni7 h w = yty.com/threads/integrata N sion-unity-as-a-library-in-native-android-ap1 j f bp.685240/