Problem analysis

In the development process of Unity’s open screen, Unity’s open screen page is usually written in Unity. When running on Android, unity_STATIC_splash is added to ensure that the display on Android will not be black. However, unity_STATIC_splash can only use image resources. If dynamic adaptation based on screen size is required, a single image cannot meet the requirements.

If the Unity open screen and Unity_STATIC_splash display the same content, the interface will jitter due to inconsistent adaptation modes.

Principle of Static Splash Image

In Unity, Static Splash Image can usually be set to shield the black screen. How can Static Splash Image be displayed on Android and disappear?

After exporting the Unity project to the Android project, you can find the image in the Drawable folder



Android terminal to start the Unity Activity is UnityPlayerActivity, analysis of the source process

//UnityPlayerActivity  
@Override protected void onCreate(Bundle savedInstanceState)
    {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);

        String cmdLine = updateUnityCommandLineArguments(getIntent().getStringExtra("unity"));
        getIntent().putExtra("unity", cmdLine);

        mUnityPlayer = new UnityPlayer(this);
        setContentView(mUnityPlayer);
        mUnityPlayer.requestFocus();
    }

Copy the code

UnityPlayer is a FrameLayout implementation

// UnityPlayer
public UnityPlayer(Context var1) {
    super(var1);
    if (var1 instanceof Activity) {
      currentActivity = (Activity)var1;
      this.c = currentActivity.getRequestedOrientation();
    }

    a(currentActivity);
    this.q = var1;
    if(currentActivity ! =null && this.k()) {
      this.m = new l(this.q, com.unity3d.player.l.a.a()[this.getSplashMode()]);
      this.addView(this.m); }... . }Copy the code

Analyze the code, new L added to the layout, guess should be this class

//l  
public l(Context var1, int var2) {
    super(var1);
    this.a = var2;
    this.b = this.getResources().getIdentifier("unity_static_splash"."drawable".this.getContext().getPackageName());
    if (this.b ! =0) {
      this.forceLayout(); }}Copy the code

As you can see, the L class is also a View that reads unity_STATIC_splash and adds it to the parent layout. That’s how unity_STATIC_splash works

Black screen optimization

The condition for a black screen is that unity_STATIC_splash cannot be used

  1. The layout needs to be adjusted to fit the screen
  2. Play videos or other resources

Add a custom layout to display the opening screen

In view of the above situation, we can write the layout manually and then add it to the layout of UnityPlayerActivityd to realize the open screen display

//MyUnityPlayerActivity  
@Override protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    ViewGroup layoutView = (FrameLayout) View.inflate(this, R.layout.activity_splash, null);
    addContentView(layoutView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT));
  }
Copy the code

Add custom layouts to display arbitrary content. You also need to set the Static Splash Image in Unity to null

About adding layout disappear

After you add the open screen for the custom display, you need to figure out when to let the custom layout disappear. Two kinds of schemes

  1. AndroidJavaObject, in Unity to call the Android function to close the layout.
  2. Use delay mechanism, set 1s or 0.5s after closing

Both options have problems

  1. Option 1 results in partial occlusion of Unity’s open screen content
  2. The opening time of Unity display is uncertain. The delay may be short or long. If the delay is short, a black screen will appear (because there is no unity_STATIC_splash), and if the delay is long, the Unity screen will be blocked.

Analyze the disappearance time of unity_STATIC_splash and find the appropriate time to disable the custom layout

//MyUnityPlayerActivity    
private void a(a) {
    this.a(new Runnable() {
      public final void run(a) {
        UnityPlayer.this.removeView(UnityPlayer.this.m);
        UnityPlayer.f(UnityPlayer.this); }}); }Copy the code

UnityPlayer closes the unity_static_splash interface by removing the layout, so you can listen for the parent layout’s child View to be removed. If it is L, then unity_static_splash is closed. We can also turn off our own custom layout

Disable custom layout

//MyUnityPlayerActivity
  @Override protected void onCreate(Bundle bundle) {
    super.onCreate(bundle); . . mUnityPlayer.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
      @Override public void onChildViewAdded(View parent, View child) {}@Override public void onChildViewRemoved(View parent, View child) {
          // Turn off the custom layout
        if (child instanceofcom.unity3d.player.l) { removeSplashLayout(); }}});Copy the code

Add layout listener, determine type, and turn off custom layout