Unity Splash之前会有几秒的黑屏,即使是打个空包也会有一两秒,很难接受,所以要解决这个问题必须写Java代码,在安卓app启动时展示Splash logo,而不是在Unity activity中展示。
Unity Splash原理
Unity的Splash就是Unity logo或者你自定义的logo出现的那个界面。Splash界面会在第一个场景加载前出现,直到第一个场景Awake的时候才关闭。
实际运行我们会发现,即使是空工程也会先黑屏1-2秒再显示Splash,然后才会进入首个场景。这个原因是打出来的apk包需要先调用UnityPlayerActivity,在UnityPlayerActivity出来之前当然是黑屏。
解决思路
要想打开应用程序直接显示logo,只有在Java层写一个继承UnityPlayerActivity的Activity用于启动,创建时直接显示Java层的Splash。
再写一个用来管理Splash加载、显示、隐藏的类。加载Splash图片新建View之后添加到Unity的View里,并且设置View的长宽为Unity视图的长宽,这样可以保证不会变形。
实际情况下只需要写一个继承UnityPlayerActivity的类就足够了,写两个函数分别控制logo的显示与隐藏即可。
软件版本
Unity 2017.4.16f1 64bit
Android Studio 3.6.1
解决过程
Android Studio 3.6.1 新建Module
把Unity的classes.jar复制到Module的libs文件夹中,classes.jar的位置在\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar
然后把jar包添加到依赖,这样在Java中才可以调用Unity的接口,继承UnityPlayerActivity。
给Module添加ActivityClass,之后导出的jar包就是这个class。
Name可以随便写一个,点OK生成。
代码结构
类名我用的是SplashActivity,代码结构如下,后面会放完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.test.splash;
public class SplashActivity extends UnityPlayerActivity { private ImageView logoView = null;
@Override protected void onCreate(Bundle bundle){ super.onCreate(bundle); onShowSplash(); }
public void onShowSplash(){ }
public void onHideSplash(){ } }
|
首先SplashActivity要继承UnityPlayerActivity,这样可以在UnityPlayerActivity创建的时候调用到SplashActivity的onCreate,以此实现尽快的展示Splash logo。
然后写一个onHideSplash方法提供给Unity调用,用来隐藏logo。
资源放置
logo的资源需要先放到Java项目中,要不然没法调用,资源应该放在图中的main\res\drawble目录下。
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| package com.test.splash;
import android.os.Bundle; import android.util.DisplayMetrics; import android.util.Log; import android.widget.ImageView;
import com.unity3d.player.UnityPlayer; import com.unity3d.player.UnityPlayerActivity;
public class SplashActivity extends UnityPlayerActivity { private ImageView logoView = null;
@Override protected void onCreate(Bundle bundle){ super.onCreate(bundle); onShowSplash(); }
public void onShowSplash(){ Log.d("Unity","----------------onShowSplash"); if(logoView != null){ Log.d("Unity","------------------logoView==null"); return; } try{ DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); float scaleX = dm.widthPixels/1366f; float scaleY = dm.heightPixels/768f; Log.d("Unity", "Screen Width:"+dm.widthPixels+";Screen Height:"+dm.heightPixels);
logoView = new ImageView(this); logoView.setImageResource(R.drawable.logo);
mUnityPlayer.addView(logoView); Log.d("Unity","------------------addView");
logoView.setScaleX(scaleX); logoView.setScaleY(scaleY); } catch (Exception e) { e.printStackTrace(); } }
public void onHideSplash() { try { if(logoView != null){ UnityPlayer.currentActivity.runOnUiThread(new Runnable() { @Override public void run() { Log.d("Unity", "onHideSplash run"); mUnityPlayer.removeView(logoView); logoView = null; } }); } }catch (Exception e) { e.printStackTrace(); } } }
|
AndroidManifest.xml
除了代码还要设置AndroidManifest,指定你写的activity所在的包名com.test.splash.SplashActivity,这样启动入口就变成你写的SplashActivity了
1 2 3 4 5 6 7 8 9 10 11 12 13
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test.splash"> <uses-permission android:name="android.permission.VIBRATE"></uses-permission> <application> <activity android:name="com.test.splash.SplashActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
|
构建jar包
写完就要构建jar包给Unity使用了,要编辑splash的build.gradle,添加以下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| task makeJar(type: Copy) { delete 'build/libs/' + "splash.jar" from("build/intermediates/aar_main_jar/release") into('build/libs/') include('classes.jar') rename('classes.jar', "splash.jar") } makeJar.dependsOn(build)
|
点击Android Studio的菜单-View-Tool Windows-Gradle,右侧会出现gradle指令,找到Tasks中Other下面的makeJar双击构建jar包。
构建成功的话会在splash\build\libs目录下出现splash.jar
Unity调用
把构建好的jar包和AndroidManifest放到Unity工程路径的Assets\Plugins\Android目录下
logo图片放在Unity工程路径的Assets\Plugins\Android\res\drawable目录下
最终在Unity中合适的时机,调用onHideSplash关闭logo即可。
1 2 3 4 5 6 7
| void Start () { #if (UNITY_ANDROID && !UNITY_EDITOR) AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("onHideSplash"); #endif }
|
参考
https://www.jianshu.com/p/8256c0da444a
https://www.jianshu.com/p/5c1f438e07f1
https://www.jianshu.com/p/2dd6cf0da2be