赞
踩
上一篇介绍了Xcode项目集成Unity的步骤,本篇介绍AS项目集成Unity,其实在AS上集成相比Xcode简单多了,但也有不少坑需要注意。我们知道Unity可以直接打包apk,也可以导出AS或Eclipse工程,我的应用场景是已经有个Android Studio大项目了,Unity所做的功能属于其一部分,所以选择将Unity导出AS工程,为了方便主项目调用,还将Unity部分打包成aar。
环境:Android Studio 3.0 + Unity 2017
如下图红框处,Build System选择Gradle,Export Project勾选,按图中箭头把包名填好,不能使用Unity默认的,否则导出不了,点击Export导出。
导出结果:
导入多半是会报错的,一般错误就是gradle版本没选对,按自己的情况选好就行了,比如我的是3.0.0。
此时我们来看看这个工程结构,就一个界面UnityPlayerActivity,因为做Unity游戏的话也不需要显示其它原生界面,网上有些教程就是用继承UnityPlayerActivity的方法来显示Unity,然而这样做不够灵活。查看UnityPlayerActivity我们可以发现真正关键的是UnityPlayer所以仿照UnityPlayerActivity直接操作UnityPlayer不就好了么,但是。。。但是这里有个坑,我直接用UnityPlayer正确显示了Unity界面,可是在退出含Unity界面的Activity时,整个应用退出了,难道有Bug导致整个应用崩了?经过查找,发现原来在UnityPlayer源码中:
这个kill方法在Activity finish时会被调用,然而它竟然给我把当前应用进程杀死了!没办法,自己写个类 MyUnityPlayer 继承它,并重写父类的kill方法。
package com.unity.demo; import android.content.Context; import com.unity3d.player.UnityPlayer; public class MyUnityPlayer extends UnityPlayer { public MyUnityPlayer(Context context) { super(context); } @Override protected void kill() { //不要杀死当前应用进程 } }
百度“Android Studio导出aar包”,发现还要创建Module,有那么麻烦吗?直接改build.gradle就行了。如下图,apply plugin: ‘com.android.application’ 改为 apply plugin: ‘com.android.library’,注释掉applicationId,然后Rebuild Project。完成后在工程的build - outputs - aar文件夹下就可以看到aar包了。
这里我就用一个简单的Demo来演示,把aar文件放入新工程的app - libs文件夹下,修改app的build.gradle:
Demo项目用两个界面呈现,主界面和第二界面,Unity内容使用FrameLayout或LinearLayout显示,代码如下:
package com.my.unityapp; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button firstButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); firstButton = findViewById(R.id.firstButton); firstButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intent); } }); } }
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.my.unityapp.MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="First Activity" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.032" /> <Button android:id="@+id/firstButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="跳转到Unity界面" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView" /> </android.support.constraint.ConstraintLayout>
package com.my.unityapp; import android.app.Activity; import android.content.Intent; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.os.Bundle; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import com.unity.demo.MyUnityPlayer; import com.unity3d.player.UnityPlayer; public class SecondActivity extends Activity { private LinearLayout unityLayout; private Button secondButton; private MyUnityPlayer mUnityPlayer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); unityLayout = findViewById(R.id.unityLayout); secondButton = findViewById(R.id.secondButton); secondButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { SecondActivity.this.finish(); } }); getWindow().setFormat(PixelFormat.RGBX_8888); // <--- This makes xperia play happy // 创建Unity视图 mUnityPlayer = new MyUnityPlayer(this); // 添加Unity视图 unityLayout.addView(mUnityPlayer.getView()); mUnityPlayer.requestFocus(); } @Override protected void onNewIntent(Intent intent) { // To support deep linking, we need to make sure that the client can get access to // the last sent intent. The clients access this through a JNI api that allows them // to get the intent set on launch. To update that after launch we have to manually // replace the intent with the one caught here. setIntent(intent); } // Quit Unity @Override protected void onDestroy () { mUnityPlayer.quit(); super.onDestroy(); } // Pause Unity @Override protected void onPause() { super.onPause(); mUnityPlayer.pause(); } // Resume Unity @Override protected void onResume() { super.onResume(); mUnityPlayer.resume(); } // Low Memory Unity @Override public void onLowMemory() { super.onLowMemory(); mUnityPlayer.lowMemory(); } // Trim Memory Unity @Override public void onTrimMemory(int level) { super.onTrimMemory(level); if (level == TRIM_MEMORY_RUNNING_CRITICAL) { mUnityPlayer.lowMemory(); } } // This ensures the layout will be correct. @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mUnityPlayer.configurationChanged(newConfig); } // Notify Unity of the focus change. @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); mUnityPlayer.windowFocusChanged(hasFocus); } // For some reason the multiple keyevent type is not supported by the ndk. // Force event injection by overriding dispatchKeyEvent(). @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_MULTIPLE) return mUnityPlayer.injectEvent(event); return super.dispatchKeyEvent(event); } // Pass any events not handled by (unfocused) views straight to UnityPlayer @Override public boolean onKeyUp(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } /*API12*/ public boolean onGenericMotionEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp" tools:context="com.my.unityapp.SecondActivity"> <LinearLayout android:id="@+id/unityLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="8dp" android:layout_weight="10" android:orientation="horizontal" app:layout_constraintTop_toTopOf="parent" tools:layout_editor_absoluteX="104dp"> </LinearLayout> <Button android:id="@+id/secondButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginTop="8dp" android:layout_weight="1" android:text="退出当前页面" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@+id/unityLayout" tools:layout_editor_absoluteX="154dp" /> </LinearLayout>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。