关于Unity启动时间过长(启动黑屏时间长)的问题

来源:互联网 发布:闲鱼网淘宝二手电脑版 编辑:程序博客网 时间:2024/04/30 09:46

好吧,Unity启动确实比其他引擎生成的游戏包慢些。关键是你启动的时候还要等上一段时间才显示Splash那个logo图。

最近项目有个蛋疼得需求,需要在启动界面加进度帧动画。。我也是醉了。

刚开始的思路:用Unity单独做个启动场景,让Splash那张图用成纯黑。那么问题来了,除了Unity刚启动的黑屏+显示Splash的黑图,再到显示loading动画界面至游戏场景加载出来,这时间都在十多秒以上了,。项目要求游戏从启动到显示游戏场景不能超过5秒。。哎。。太难为我了。好长一段时间都没能解决这个问题。

中间还想到一个方案就是用Android做一个插件的启动Activity场景,然后把这个场景设置成启动场景,之后再到Unity的场景。但是这个问题是无法绕过Unity的启动Splash。。无奈放弃。

因为不熟悉Android开发,所以。。。

我分析了Unity生成Android,对就是从Unity的UnityPlayerActivity入手。既然绕不过,那就不绕过,思路:

1、Unity生成的Android应用必然要从这个UnityPlayerActivity启动,那么他的启动Splash view必然显示在这个activity里面;

2、那么我可以继承UnityPlayerActivity,然后在onCreate方法里面在创建一个view来覆盖Splash,是的。这是可行的。激动。。。。。。

3、那这个启动界面上我们也同样可以做动画咯,O(∩_∩)O哈哈~现在的问题是当Unity Splash显示完毕之后,或者初始化完成之后怎么来隐藏我们所创建的View和动画。

4、现在我们要在Unity建一个空场景用来加载我们的第一个游戏场景,当加载完成之后通知我们的自定义Activity移除我们创建的界面和动画,是不是很完美呢?

现在不用看黑屏了,也绕过了Unity的Splash,只是加载的时间还是比其他引擎慢了,不过也能接受,因为很快的 就开到了我们的启动动画界面,等待加载到游戏场景。

最后贴点代码上来。。。。

package com.u3d.plugins;import java.util.Locale;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.drawable.AnimationDrawable;import android.media.AudioManager;import android.media.AudioManager.OnAudioFocusChangeListener;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.util.DisplayMetrics;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.widget.ImageView;import com.unity3d.player.UnityPlayerActivity;public class MainActivity extends UnityPlayerActivity {static final String TAG = "com.u3d.plugins";private ImageView bgView = null;private View view = null;AnimationDrawable animationDrawable = null;@SuppressLint("NewApi") @Overrideprotected void onCreate(Bundle arg0) {super.onCreate(arg0);bgView=new ImageView(this);String lanStr=Locale.getDefault().getLanguage();String bgName="splash_bg_en";if(lanStr.equals("zh")){bgName="splash_bg_zh";}Log.d(TAG, "System Lan:"+bgName);int splash_bg=getResources().getIdentifier(bgName, "drawable", getPackageName());bgView.setBackgroundResource(splash_bg);//this.addContentView(bgView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));mUnityPlayer.addView(bgView);DisplayMetrics dm = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);float scaleX=dm.widthPixels/1024f;float scaleY=dm.heightPixels/600f;Log.d(TAG, "Screen Width:"+dm.widthPixels+";Screen Height:"+dm.heightPixels);LayoutInflater flater = LayoutInflater.from(this); int layoutID=getResources().getIdentifier("activity_splash", "layout", getPackageName());view = flater.inflate(layoutID, null);int frame_id=view.getResources().getIdentifier("splash_frame", "id", getPackageName());ImageView frameView=(ImageView)view.findViewById(frame_id);//new ImageView(this);frameView.setBackgroundResource(R.anim.splash_gif);//this.addContentView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));mUnityPlayer.addView(view);frameView.setScaleX(scaleX);frameView.setScaleY(scaleY);//frameView=new ImageView(this);//frameView.setBackgroundResource(R.anim.splash_gif);////LinearLayout ll=new LinearLayout(this);//LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);//params.leftMargin=scaleX*620;//ll.setLayoutParams(params);//ll.addView(frameView);//mUnityPlayer.addView(ll);animationDrawable = (AnimationDrawable) frameView.getBackground();animationDrawable.start();}public void HideSplash(){Log.d(TAG, "HideSplash");new Handler(Looper.getMainLooper()).post(new Runnable(){@Overridepublic void run(){Log.d(TAG, "HideSplash run");animationDrawable.stop();mUnityPlayer.removeView(bgView);mUnityPlayer.removeView(view);//((ViewGroup)bgView.getParent()).removeView(bgView);//((ViewGroup)view.getParent()).removeView(view);bgView=null;view=null;animationDrawable=null;}});}@Overrideprotected void onRestart() {// TODO Auto-generated method stubsuper.onRestart();Log.d(TAG, "onRestart");new Handler(Looper.getMainLooper()).post(new Runnable(){@Overridepublic void run(){muteAudioFocus(MainActivity.this,true);}});}@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();}@Overrideprotected void onPause() {// TODO Auto-generated method stubsuper.onPause();}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();}@Overrideprotected void onStop() {// TODO Auto-generated method stubsuper.onStop();Log.d(TAG, "onStop");new Handler(Looper.getMainLooper()).post(new Runnable(){@Overridepublic void run(){muteAudioFocus(MainActivity.this,false);}});}@Overrideprotected void onStart() {// TODO Auto-generated method stubsuper.onStart();Log.d(TAG, "onStart");new Handler(Looper.getMainLooper()).post(new Runnable(){@Overridepublic void run(){muteAudioFocus(MainActivity.this,true);}});}/**@param bMute 值为true时为关闭背景音乐。*/public boolean muteAudioFocus(Context context, boolean bMute) {if(context == null){Log.d(TAG, "context is null.");return false;}boolean bool = false;AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);if(bMute){int result = am.requestAudioFocus(afChangeListener,AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN);bool = result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;}else{int result = am.abandonAudioFocus(afChangeListener);bool = result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;}Log.d(TAG, "pauseMusic bMute="+bMute +" result="+bool);return bool;}OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {      public void onAudioFocusChange(int focusChange)     {  Log.d(TAG, "focusChange:"+focusChange);        if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT)        {              // Pause playback           }        else if (focusChange == AudioManager.AUDIOFOCUS_LOSS)         {          muteAudioFocus(MainActivity.this,false);            // Stop playback           }         else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)        {              // Lower the volume           }         else if (focusChange == AudioManager.AUDIOFOCUS_GAIN)        {              // Resume playback or Raise it back to normal           }      }  };  }

Unity的启动场景代码:

using UnityEngine;using System.Collections;public class Launcher : MonoBehaviour{    public string loadScene;    void Awake()    {        Debug.Log("Launcher Awake");        DontDestroyOnLoad(gameObject);    }    void Start()    {        Debug.Log("Launcher Start");        StartCoroutine(LoadSence());    }    IEnumerator LoadSence()    {        if (!string.IsNullOrEmpty(loadScene))        {            Application.LoadLevelAsync(loadScene);        }        else        {            int levelCount = Application.levelCount;            int curLevel = Application.loadedLevel;            if (curLevel + 1 < levelCount)                Application.LoadLevelAsync(curLevel + 1);        }        yield return 0;        Invoke("OnFinish", 0.5f);        //OnFinish();    }    void OnFinish()    {        if (Application.platform.Equals(RuntimePlatform.Android))        {            using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))            {                using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"))                {                    jo.Call("HideSplash");                }            }        }        Destroy(gameObject);    }}
最后把我们的Android项目生成jar包供Unity使用

anim文件夹放了动画得的配置文件,layout布局文件。

<?xml version="1.0" encoding="utf-8"?><manifest    xmlns:android="http://schemas.android.com/apk/res/android"    package="com.unity3d.player"android:installLocation="preferExternal"    android:versionCode="1"    android:versionName="1.0">    <supports-screens        android:smallScreens="true"        android:normalScreens="true"        android:largeScreens="true"        android:xlargeScreens="true"        android:anyDensity="true"/>    <applicationandroid:theme="@android:style/Theme.NoTitleBar.Fullscreen"android:icon="@drawable/launcher_icon"        android:label="@string/app_name"        android:debuggable="true">        <activity android:name="com.u3d.plugins.MainActivity"                  android:label="@string/app_name">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />        </activity>    </application></manifest>


<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/splash_bg"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="horizontal" >  <LinearLayout      android:layout_width="wrap_content"      android:layout_height="match_parent"      android:layout_weight="6.3"      android:orientation="horizontal" />  <LinearLayout        android:layout_width="wrap_content"        android:layout_height="match_parent"              android:layout_weight="3.7"        android:orientation="vertical" >  <LinearLayout      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:layout_weight="7.86"      android:orientation="horizontal" />    <LinearLayout      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:layout_weight="2.14"      android:orientation="horizontal" >              <ImageView        android:id="@+id/splash_frame"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/>          </LinearLayout>    </LinearLayout></LinearLayout>

<?xml version="1.0" encoding="UTF-8"?><animation-list android:oneshot="false"  xmlns:android="http://schemas.android.com/apk/res/android">    <item android:duration="300" android:drawable="@drawable/loading_1" />    <item android:duration="300" android:drawable="@drawable/loading_2" />    <item android:duration="300" android:drawable="@drawable/loading_3" /></animation-list>


0 0