Splash设置相信搞unity的朋友都知道这个东西,就是游戏启动的时候的启动画面,在unity中如果不设置splash的话我们就能够看到unity游戏启动的时候就会出现一张unity默认的带有Unity标志的splash启动页,如果我们需要换成自己的启动页就需要在打包的时候把splash设置成自己的图片。
那么Unity为什么会有启动页这么一个东西呢?
其实在我们游戏启动的时候unity或者我们自己会有一系列的资源加载或者初始化的东西,而这些操作都需要时间来完成,如果没有splash的话就会造成一种卡机的假象。当unity所有的初始化都完成并加载第一个场景完成,unity就会自动的隐藏splash。
那么可能有很多朋友就有疑问了,既然unity自带了splash的设置我们为什么还要重写splash呢?
答案:不知道大家有没有注意到,在我们启动unity游戏的时候会出现一段时间的黑屏然后才出现我们设置好的splash,如果机器配置越差,黑屏时间就越长。为了解决这个黑屏时间,我们重写了splash功能,让我们游戏一启动就出现我们的splash启动页。
接下来我们说一说重写splash的流程:
重写splash会涉及到好4个流程,1、编写JAVA层splash加载和处理代码 2、设置Unity中的splash 3、编写unity层隐藏splash代码 4、splash图片资源路径设置
1、编写JAVA层splash加载和处理代码
在这一流程中我们首先需要编写我们自己的程序启动Activity,此Activity继承UnityPlayerActivity,因为我们需要在主Activity onCreate()的时候显示我们JAVA层的splash。
再写一个专门管理splash加载、显示和隐藏的类。这个类的职责就是负责splash的加载、显示、隐藏。
在加载了splash图片新建view后我们需要把他加到Unity的View中,并且设置我们新建view的长宽为我们的Unity视图的长宽这样才能保证我们加载的splash跟unity中设置的splash一样而不会变形。
2、设置Unity中的splash
这个过程是必要的,因为unity加载第一个场景的时候是需要时间的,而这段时间unity会使用splash来进行覆盖,而且还会涉及到隐藏splash时机的问题。
3、编写unity层隐藏splash代码
第二点说了一下隐藏时机的问题,可能大部分人都会认为unity splash消失后才会执行启动场景中的Awake。但是我很确定的告诉你,并不是你想想的那样。
其实在Awake执行后splash才会消失,而这段时间是不可预估的,所以如果我们不设置Unity自带的splash页面就会造成我们无法知道的splash什么时候去隐藏他。
所以设置了unity的自带splash后我们就能光明正大的把隐藏的代码放到启动场景的Awake中去执行了。
4、splash图片资源路径设置
如果明白了上面的思路,那么最后一步就是设置我们的splash资源路径了。而这一步我们要设置2个地方的资源,一个是Android层加载的splash的位置,一个是Unity层设置的splash的位置。
可能你要问,unity层的splash设置不就是直接把图片拖到设置面板中么,但是这次我们不这样做,其实搞懂了unity设置的splash最后在Android包中哪个位置那么你就了解我要怎么做了。
注意:splash图片必须是png图片并且名字是splash.png
Android层的splash设置:放入Assets\Plugins\Android\res\drawable中
Unity层的splash设置:放入Assets\Plugins\Android\assets\bin\Data中,不需要再设置面板中去设置splash,所以大家明白了unity设置的splash最后就是在assets\bin\Data中。
一般Android层和unity层的splash应该是同一张图片,当然你也可以不一样。
有朋友推荐了一篇博客:我抽空看了一下他的做法,基本的做法没有什么区别,最大的区别是我增加了一步就是设置unity的自身启屏页。我来解释一下为什么要这么做。
在上面博客的代码中我们可以看到最后他隐藏splsh的代码是在start里面Invoke("OnFinish", 0.5f),这就说明他延迟了0.5s来隐藏splash,但是我很明确的是他这个做法是不准确的,因为unity隐藏splash的时机是不确定的,这种做法会导致splash提前或者延后隐藏,这完全取决于机器的性能。
我的做法是在启动场景awake之前是靠Android层的splash覆盖unitysplash,Awake之后就是显示的unity自己的splash,最后隐藏是unity的自身行为,这种方式保证了unity的百分百准确隐藏splash。
实例代码:
package com.zwwx.jsws;
import com.unity3d.player.UnityPlayer;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
public class Splash extends SDKBase{
private ImageView bgView = null;
private UnityPlayer mUnityPlayer = null;
private static Splash mInstance;
public static Splash getInstance() {
if (null == mInstance) {
synchronized (Splash.class) {
if (null == mInstance) {
mInstance = new Splash();
}
}
}
return mInstance;
}
@Override
public void onCreate(Activity activity, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(activity, savedInstanceState);
mUnityPlayer = ((ZWWXActivity)mActivity).getUnityPlayer();
onShowSplash();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
onHideSplash();
}
@SuppressLint("NewApi")
public void onShowSplash() {
if (bgView != null)
return;
try {Resources r = UnityPlayer.currentActivity.getResources();
bgView = new ImageView(UnityPlayer.currentActivity);
int splash_bg = r.getIdentifier("splash", "drawable",
UnityPlayer.currentActivity.getPackageName());
bgView.setBackgroundResource(splash_bg);
bgView.setScaleType(ScaleType.CENTER);
mUnityPlayer.addView(bgView,r.getDisplayMetrics().widthPixels,
r.getDisplayMetrics().heightPixels);
} catch (Exception e) {
error("[onShowSplash]"+e.toString());
}
}
public void onHideSplash() {
try {
if(bgView == null)
return;
UnityPlayer.currentActivity.runOnUiThread(new Runnable() {
public void run() {
mUnityPlayer.removeView(bgView);
bgView = null;
}
});
} catch (Exception e) {
error("[onHideSplash]"+e.toString());
}
}
}