Unity3D游戏开发之“重写Unity Android Splash,实现启动无黑屏”

转自:http://www.manew.com/thread-98428-1-1.html


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应该是同一张图片,当然你也可以不一样。



有朋友推荐了一篇博客:http://blog.csdn.net/u012169685/article/details/52068809我抽空看了一下他的做法,基本的做法没有什么区别,最大的区别是我增加了一步就是设置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());

                }

        }

}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值