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

好吧,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,只是加载的时间还是比其他引擎慢了,不过也能接受,因为很快的 就开到了我们的启动动画界面,等待加载到游戏场景。

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

[java]  view plain  copy
 
  1. package com.u3d.plugins;  
  2.   
  3. import java.util.Locale;  
  4.   
  5. import android.annotation.SuppressLint;  
  6. import android.content.Context;  
  7. import android.graphics.drawable.AnimationDrawable;  
  8. import android.media.AudioManager;  
  9. import android.media.AudioManager.OnAudioFocusChangeListener;  
  10. import android.os.Bundle;  
  11. import android.os.Handler;  
  12. import android.os.Looper;  
  13. import android.util.DisplayMetrics;  
  14. import android.util.Log;  
  15. import android.view.LayoutInflater;  
  16. import android.view.View;  
  17. import android.widget.ImageView;  
  18.   
  19. import com.unity3d.player.UnityPlayerActivity;  
  20.   
  21. public class MainActivity extends UnityPlayerActivity   
  22. {  
  23.     static final String TAG = "com.u3d.plugins";  
  24.     private ImageView bgView = null;  
  25.     private View view = null;  
  26.     AnimationDrawable animationDrawable = null;  
  27.       
  28.     @SuppressLint("NewApi"@Override  
  29.     protected void onCreate(Bundle arg0)   
  30.     {  
  31.         super.onCreate(arg0);  
  32.                   
  33.         bgView=new ImageView(this);  
  34.         String lanStr=Locale.getDefault().getLanguage();  
  35.         String bgName="splash_bg_en";  
  36.         if(lanStr.equals("zh"))  
  37.         {  
  38.             bgName="splash_bg_zh";  
  39.         }  
  40.         Log.d(TAG, "System Lan:"+bgName);  
  41.         int splash_bg=getResources().getIdentifier(bgName, "drawable", getPackageName());  
  42.         bgView.setBackgroundResource(splash_bg);  
  43. //      this.addContentView(bgView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));  
  44.         mUnityPlayer.addView(bgView);  
  45.           
  46.         DisplayMetrics dm = new DisplayMetrics();  
  47.         getWindowManager().getDefaultDisplay().getMetrics(dm);  
  48.         float scaleX=dm.widthPixels/1024f;  
  49.         float scaleY=dm.heightPixels/600f;  
  50.         Log.d(TAG, "Screen Width:"+dm.widthPixels+";Screen Height:"+dm.heightPixels);  
  51.         LayoutInflater flater = LayoutInflater.from(this);   
  52.         int layoutID=getResources().getIdentifier("activity_splash""layout", getPackageName());  
  53.         view = flater.inflate(layoutID, null);  
  54.               
  55.         int frame_id=view.getResources().getIdentifier("splash_frame""id", getPackageName());  
  56.         ImageView frameView=(ImageView)view.findViewById(frame_id);//new ImageView(this);  
  57.         frameView.setBackgroundResource(R.anim.splash_gif);  
  58. //      this.addContentView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));  
  59.         mUnityPlayer.addView(view);  
  60.           
  61.         frameView.setScaleX(scaleX);  
  62.         frameView.setScaleY(scaleY);  
  63.           
  64. //      frameView=new ImageView(this);  
  65. //      frameView.setBackgroundResource(R.anim.splash_gif);  
  66. //        
  67. //      LinearLayout ll=new LinearLayout(this);  
  68. //      LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);  
  69. //      params.leftMargin=scaleX*620;  
  70. //      ll.setLayoutParams(params);  
  71. //      ll.addView(frameView);  
  72. //      mUnityPlayer.addView(ll);  
  73.           
  74.         animationDrawable = (AnimationDrawable) frameView.getBackground();  
  75.         animationDrawable.start();  
  76.     }  
  77.     public void HideSplash()  
  78.     {  
  79.         Log.d(TAG, "HideSplash");  
  80.         new Handler(Looper.getMainLooper()).post(new Runnable()  
  81.         {  
  82.             @Override  
  83.             public void run()  
  84.             {  
  85.                 Log.d(TAG, "HideSplash run");  
  86.                 animationDrawable.stop();  
  87.                 mUnityPlayer.removeView(bgView);  
  88.                 mUnityPlayer.removeView(view);  
  89. //              ((ViewGroup)bgView.getParent()).removeView(bgView);  
  90. //              ((ViewGroup)view.getParent()).removeView(view);  
  91.                 bgView=null;  
  92.                 view=null;  
  93.                 animationDrawable=null;  
  94.             }  
  95.         });  
  96.     }  
  97.     @Override  
  98.     protected void onRestart() {  
  99.         // TODO Auto-generated method stub  
  100.         super.onRestart();  
  101.         Log.d(TAG, "onRestart");  
  102.         new Handler(Looper.getMainLooper()).post(new Runnable()  
  103.         {  
  104.             @Override  
  105.             public void run()  
  106.             {  
  107.                 muteAudioFocus(MainActivity.this,true);  
  108.             }  
  109.         });  
  110.     }  
  111.     @Override  
  112.     protected void onResume() {  
  113.         // TODO Auto-generated method stub  
  114.         super.onResume();  
  115.     }  
  116.     @Override  
  117.     protected void onPause()   
  118.     {  
  119.         // TODO Auto-generated method stub  
  120.         super.onPause();  
  121.     }  
  122.     @Override  
  123.     protected void onDestroy() {  
  124.         // TODO Auto-generated method stub  
  125.         super.onDestroy();  
  126.     }  
  127.     @Override  
  128.     protected void onStop() {  
  129.         // TODO Auto-generated method stub  
  130.         super.onStop();  
  131.         Log.d(TAG, "onStop");  
  132.         new Handler(Looper.getMainLooper()).post(new Runnable()  
  133.         {  
  134.             @Override  
  135.             public void run()  
  136.             {  
  137.                 muteAudioFocus(MainActivity.this,false);  
  138.             }  
  139.         });  
  140.     }  
  141.     @Override  
  142.     protected void onStart() {  
  143.         // TODO Auto-generated method stub  
  144.         super.onStart();  
  145.         Log.d(TAG, "onStart");  
  146.         new Handler(Looper.getMainLooper()).post(new Runnable()  
  147.         {  
  148.             @Override  
  149.             public void run()  
  150.             {  
  151.                 muteAudioFocus(MainActivity.this,true);  
  152.             }  
  153.         });  
  154.     }  
  155.     /**@param bMute 值为true时为关闭背景音乐。*/  
  156.     public boolean muteAudioFocus(Context context, boolean bMute)   
  157.     {  
  158.         if(context == null)  
  159.         {  
  160.             Log.d(TAG, "context is null.");  
  161.             return false;  
  162.         }  
  163.         boolean bool = false;  
  164.         AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);  
  165.         if(bMute)  
  166.         {  
  167.             int result = am.requestAudioFocus(afChangeListener,AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN);  
  168.             bool = result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;  
  169.         }  
  170.         else  
  171.         {  
  172.             int result = am.abandonAudioFocus(afChangeListener);  
  173.             bool = result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;  
  174.         }  
  175.         Log.d(TAG, "pauseMusic bMute="+bMute +" result="+bool);  
  176.         return bool;  
  177.     }  
  178.     OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener()   
  179.     {    
  180.         public void onAudioFocusChange(int focusChange)   
  181.         {    
  182.             Log.d(TAG, "focusChange:"+focusChange);  
  183.             if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT)  
  184.             {    
  185.                 // Pause playback     
  186.             }  
  187.             else if (focusChange == AudioManager.AUDIOFOCUS_LOSS)   
  188.             {    
  189.                 muteAudioFocus(MainActivity.this,false);  
  190.                 // Stop playback     
  191.             }   
  192.             else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)  
  193.             {    
  194.                 // Lower the volume     
  195.             }   
  196.             else if (focusChange == AudioManager.AUDIOFOCUS_GAIN)  
  197.             {    
  198.                 // Resume playback or Raise it back to normal     
  199.             }    
  200.         }    
  201.     };    
  202. }  

Unity的启动场景代码:

[csharp]  view plain  copy
 
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class Launcher : MonoBehaviour  
  5. {  
  6.     public string loadScene;  
  7.     void Awake()  
  8.     {  
  9.         Debug.Log("Launcher Awake");  
  10.         DontDestroyOnLoad(gameObject);  
  11.     }  
  12.     void Start()  
  13.     {  
  14.         Debug.Log("Launcher Start");  
  15.         StartCoroutine(LoadSence());  
  16.     }  
  17.     IEnumerator LoadSence()  
  18.     {  
  19.         if (!string.IsNullOrEmpty(loadScene))  
  20.         {  
  21.             Application.LoadLevelAsync(loadScene);  
  22.         }  
  23.         else  
  24.         {  
  25.             int levelCount = Application.levelCount;  
  26.             int curLevel = Application.loadedLevel;  
  27.             if (curLevel + 1 < levelCount)  
  28.                 Application.LoadLevelAsync(curLevel + 1);  
  29.         }  
  30.         yield return 0;  
  31.         Invoke("OnFinish", 0.5f);  
  32.         //OnFinish();  
  33.     }  
  34.     void OnFinish()  
  35.     {  
  36.         if (Application.platform.Equals(RuntimePlatform.Android))  
  37.         {  
  38.             using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))  
  39.             {  
  40.                 using (AndroidJavaObject jo = jc.GetStatic("currentActivity"))  
  41.                 {  
  42.                     jo.Call("HideSplash");  
  43.                 }  
  44.   
  45.             }  
  46.         }  
  47.         Destroy(gameObject);  
  48.     }  
  49. }  
最后把我们的Android项目生成jar包供Unity使用

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

[html]  view plain  copy
 
  1. xml version="1.0" encoding="utf-8"?>  
  2. <manifest  
  3.     xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     package="com.unity3d.player"  
  5.     android:installLocation="preferExternal"  
  6.     android:versionCode="1"  
  7.     android:versionName="1.0">  
  8.     <supports-screens  
  9.         android:smallScreens="true"  
  10.         android:normalScreens="true"  
  11.         android:largeScreens="true"  
  12.         android:xlargeScreens="true"  
  13.         android:anyDensity="true"/>  
  14.   
  15.     <application  
  16.         android:theme="@android:style/Theme.NoTitleBar.Fullscreen"  
  17.         android:icon="@drawable/launcher_icon"  
  18.         android:label="@string/app_name"  
  19.         android:debuggable="true">  
  20.         <activity android:name="com.u3d.plugins.MainActivity"  
  21.                   android:label="@string/app_name">  
  22.             <intent-filter>  
  23.                 <action android:name="android.intent.action.MAIN" />  
  24.                 <category android:name="android.intent.category.LAUNCHER" />  
  25.             intent-filter>  
  26.             <meta-data android:name="unityplayer.UnityActivity" android:value="true" />  
  27.         activity>  
  28.     application>  
  29. manifest>  


[html]  view plain  copy
 
  1. xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/splash_bg"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     android:orientation="horizontal" >  
  7.   
  8.     <LinearLayout  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="match_parent"  
  11.         android:layout_weight="6.3"  
  12.         android:orientation="horizontal" />  
  13.   
  14.   <LinearLayout  
  15.         android:layout_width="wrap_content"  
  16.         android:layout_height="match_parent"  
  17.                 android:layout_weight="3.7"  
  18.         android:orientation="vertical" >  
  19.     <LinearLayout  
  20.         android:layout_width="wrap_content"  
  21.         android:layout_height="wrap_content"  
  22.         android:layout_weight="7.86"  
  23.         android:orientation="horizontal" />  
  24.         <LinearLayout  
  25.         android:layout_width="wrap_content"  
  26.         android:layout_height="wrap_content"  
  27.         android:layout_weight="2.14"  
  28.         android:orientation="horizontal" >  
  29.                 <ImageView  
  30.         android:id="@+id/splash_frame"  
  31.         android:layout_width="wrap_content"  
  32.         android:layout_height="wrap_content"/>  
  33.             LinearLayout>  
  34.     LinearLayout>  
  35.   
  36. LinearLayout>  

[html]  view plain  copy
 
  1. xml version="1.0" encoding="UTF-8"?>  
  2. <animation-list android:oneshot="false"  
  3.   xmlns:android="http://schemas.android.com/apk/res/android">  
  4.     <item android:duration="300" android:drawable="@drawable/loading_1" />  
  5.     <item android:duration="300" android:drawable="@drawable/loading_2" />  
  6.     <item android:duration="300" android:drawable="@drawable/loading_3" />  
  7. animation-list>  

你可能感兴趣的:(unity游戏开发经验)