Search Unity

Indie (personal) splash continues to show after first scene loads

Discussion in 'Scripting' started by moondust-games, Mar 5, 2015.

  1. moondust-games

    moondust-games

    Joined:
    Jul 21, 2013
    Posts:
    20
    My scene 0 is my own secondary splash which should show after the Unity splash. I've set it to show for 2 seconds then load the games menu (scene 1).

    The problem is scene 0 loads, runs and finishes while the Unity splash is still showing so the first thing I see is scene 1.

    I don't know is this is since upgrading to Unity 5 or not as I have only just tried to do it.

    How can I detect when the Unity splash is actually removed off the device screen (ios in this instance) so that I can time my 2nd splash from there ? Why does it continue to show after loading the first scene?

    Any help would be great!

    Philip
     
  2. Deleted User

    Deleted User

    Guest

    Maybe you can have a game object with "OnLevelLoaded" and have "OnLevelLoaded" call a 2nd coroutine and the coroutine can load the next scene when it finishes.
     
  3. moondust-games

    moondust-games

    Joined:
    Jul 21, 2013
    Posts:
    20
    Thanks @supremegrandruler I was just trying that before I saw your reply.

    It didn't work. OnLevelLoaded is clearly also being run, after the level has loaded as it should be, but while the Unity flash screen is still showing!!

    So i tried level 0 = nothing other than loads level 1 (so I can use OnLevelLoaded on level 1)

    level 1 checks for onlevelloaded, waits 2 seconds, then loads level 2, my menu.

    However that still all happens behind the Unity splash as the next thing I see is the menu. To test I changed it to wait 10 seconds and that way I do indeed see my level 1 (secondary splash).

    However there is no way to know how long the Unity splash is going to show for so I don't know what duration to show my secondary splash for. Assuming it will be different times for different devices but I definitely want :

    1) my 2nd splash to show and
    2) to show for no more than 2 seconds.

    There's doesn't seem to be a way around this so is it a bug?
     
  4. moondust-games

    moondust-games

    Joined:
    Jul 21, 2013
    Posts:
    20
    Basically I'm looking for a way to detect when the Unity splash is no longer on screen. What event removes it? Then I can time from that point on.
     
  5. Deleted User

    Deleted User

    Guest

    One idea is maybe you could have a "Press To Start" text on your splash screen. Or you could just have your splash screen run until the player touches the screen.
     
  6. moondust-games

    moondust-games

    Joined:
    Jul 21, 2013
    Posts:
    20
    Crossed my mind but I don't want that. It looks unprofessional.

    Ive set the delay to 5 seconds and I Now get about 2 seconds of display time before it loads my menu. That's on a iPhone 4s. I'm guessing on faster devices my 2nd splash could show for up to the full 5 seconds. I don't want that :(

    I've sent a bug report to Unity as cannot find a work around.
     
  7. Deleted User

    Deleted User

    Guest

    Let us know if you find a solution. It's strange that the level would already be considered "loaded" while the splash screen is still displaying.
     
  8. Ardalan

    Ardalan

    Joined:
    Aug 16, 2013
    Posts:
    8
    I am having the same issue with unity 5, I started and almost finished my project in unity 4.x, but wanted to port my project to unity 5 to use some optimisation tools that wasn't available to free license holders in unity 4. my ios game works perfectly from a unity 4 build but in the new unity 5 build the splash screen stays on even after scene has started or another way of looking at it is the scene starts before splash screen has ended please let us know if you have figured this one out.
    ANY ONE OUT THERE is there a way to detect splash screen activity ? this way I could have an empty scene waiting to detect end of a splash screen and after that loads my real first scene, or better yet maybe unity officials can fix this
     
  9. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    333
    Can you show us the exact code you're using to delay the scene load? I think the way your handling this might be the issue because I've done some testing here, and as far as I can tell, the game does not start until after the splash screen has finished.
     
  10. Ardalan

    Ardalan

    Joined:
    Aug 16, 2013
    Posts:
    8
    I have not done anything special.
    I thought maybe there is something wrong because I imported a project from unity 4.x so I tested the same thing with a new project.
    here is what I have done (steps to recreate the bug/issue):
    open a new unity project (in the build settings switch to iOS), save an empty scene with one test object in it
    here is the code I attached to the empty object to test the time were splash screen overlaps with the first scene loaded :
    usingUnityEngine;
    usingSystem.Collections;

    public class Timer : MonoBehaviour
    {
    private float TimeSinceLevelStarted;
    private Rect Label Rect;

    voidStart ()
    {
    LabelRect = newRect(Screen.width / 4, Screen.height / 4, Screen.width / 2, Screen.height / 4);
    TimeSinceLevelStarted = 0;
    }

    voidUpdate ()
    {
    TimeSinceLevelStarted += Time.deltaTime;
    }

    voidOnGUI()
    {
    GUI.skin.label.fontSize = 30;
    GUI.Label(LabelRect, TimeSinceLevelStarted.ToString());
    }
    }

    obviously a very simple code that displays time since level loaded (could have used time function that does this but just wanted to make sure)
    now in the build setting i just added a splash screen (a simple black image) while unity splash screen is also on (as well).
    used il2cpp and architecture setting to universal (for ipad and iphone). other settings to mention is stripping level set to max (micro....)
    [just a side note this empty project with no graphical contents or sounds at all takes an outrage 88 megs on my ipad 3, seriously what is going on here?!!!!]
    in xcode I set the product scheme to release and thats it.
    first time running the app from xcode on my ipad and the splash screen ends while the timer shows near 2 sec gone,
    2nd time running the app from my ipad and it gets worse (timer shows over 4 sec)
    I am assuming this could vary depending on the device hardware and you may not notice this if your first scene is static but if like my game the first scene starts with an animation you will notice the frames you have missed
     
  11. Ardalan

    Ardalan

    Joined:
    Aug 16, 2013
    Posts:
    8
    just to add to my last post the timer should show under 1 second (0.xxxx) obviously, while it starts at (1.5xxx) at best now this 1 or 2 seconds (even more at times) maybe hard to catch.
     
  12. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    333
    OnGUI is extremely slow on mobile, so that could cause problems with your test. Time.time is also much easier than Time.deltaTime. I can only test on Android and Windows, but I don't see any issue there. The time looks to be correct for me (less than 1.0)

    Try this:
    1. Place the script below on an object in the scene.
    2. Create a large UI button in the scene.
    3. Assign the button's text element to timeHUD on the script.
    4. Assign the StopTimer method to the button's OnClick event in the inspector.
    5. Build & Run the game.
    6. Press the button as soon as you see it to freeze the timer and check the results.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. public class Timer : MonoBehaviour
    5. {
    6.     public Text timeHUD;    // UI text to display time value.
    7.     private bool tracking;    // Are we tracking the time?
    8.  
    9.     void Start ()
    10.     {
    11.         tracking = true;
    12.     }
    13.  
    14.     void Update ()
    15.     {
    16.         if (!tracking) return;
    17.         timeHUD.text = Time.time.ToString ();
    18.     }
    19.  
    20.     // Call this from UI Button "OnClick" event.
    21.     public void StopTimer ()
    22.     {
    23.         tracking = false;
    24.     }
    25. }
    Or, to automatically stop the timer, create a cube in front of the camera and place this script on the cube.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. [RequireComponent (typeof (Renderer))]
    5. public class Timer : MonoBehaviour
    6. {
    7.     public Text timeHUD; // UI text to display time value.
    8.  
    9.     // Set timer text when object becomes visible.
    10.     void OnBecameVisible ()
    11.     {
    12.         timeHUD.text = Time.time.ToString ();
    13.     }
    14. }
    For me this last script gives me a perfect result of "0", but this code also assumes that the object only becomes visible after the splash screen has played. But I don't know if that's really true? Let me know what your results are with both. This might just be a bug only in the iOS exporter
     
    Last edited: Apr 13, 2015
  13. Ardalan

    Ardalan

    Joined:
    Aug 16, 2013
    Posts:
    8
    first of all thanks Isaiah for your replies, apparently no one else is interested in this and is good to see you reply.
    on the issue there few things to note:

    I agree with you on the bug being exclusive to iOS builds.
    as for the notorious OnGUI poor performance that may be true on medium or large sized projects (Im talking about a 3D project with some polys or a 2D project with lots of draw calls and physics while you've got some complicated OnGUI function going on) but I doubt for an empty project with one label OnGUI performance could be the reason. anyway to be clear on this xcode shows 30fps no matter how slow OnGUI is for 1 second after splash screen ends you should see the timer showing under 1 second ( it shouldn't start at 2 or 3 seconds).

    on your solution (how to stop time) I doubt that works because splash screen is not a layer in front of the camera blocking your time stopping box but a layer on top of the whole thing (unless I am mistaking) but in all hope I am gonna use your idea not to stop time but start my first scene instead (as soon as the box is visible to the camera) and if it works ill buy you a drink :)
     
  14. Ardalan

    Ardalan

    Joined:
    Aug 16, 2013
    Posts:
    8
    [an update to my previous reply]
    I did try the visibility test and sadly no success (sorry mate no drinks :) )
    so as it stands the first scene starts while still the splash screen is on and the camera even detects the objects update and the rest of the functions are working while still not visible to the user.
    I am starting to feel this is a serious bug with the new splash screen system and the ios exporter and since xcode only recognises your custom splash screen as the only app's splash screen there will be no xcode solution to this.
    [I assume this might be because on personal license you are allowed a custom splash screen (the one xcode recognises) and the unity splash screen starts at the same time the game does (the delay between the 2 probably depends on scene's load time)]
    as for me I just have to take out the initial animation until they fix this (dont want to risk this with placing delays before the animation since the overlap time between splash screen end and the scene start is not consistent.
     
  15. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    333
    Sorry to hear that. I'd file a bug report for this ASAP. As a final test I used this code to make a sphere grow once it becomes visible. And it worked as expected on both Android and Windows for me. Sphere only starts growing after splash screen.

    Code (CSharp):
    1.     Transform tr;
    2.  
    3.     void Awake ()
    4.     {
    5.         tr = GetComponent <Transform> ();
    6.     }
    7.  
    8.     void OnBecameVisible ()
    9.     {
    10.         StartCoroutine (Grow ());
    11.     }
    12.  
    13.     IEnumerator Grow ()
    14.     {
    15.         while (true)
    16.         {
    17.             tr.localScale += Vector3.one/100;
    18.  
    19.             yield return null;
    20.         }
    21.     }
    But I did noticed that Unity Android is still using the old Unity splash screen strangely enough.
     
  16. Ostwind

    Ostwind

    Joined:
    Mar 22, 2011
    Posts:
    2,773
    I think there is a bug somewhere. I have a pro version but I ticked the show unity splash for a test and did a iOS build with a simple scene with music and a cube. When the unity splash came visible the music started playing before my scene was visible (it was a clip in audiosource with play on awake)
     
  17. Ardalan

    Ardalan

    Joined:
    Aug 16, 2013
    Posts:
    8
    thanks mate your help is very much appreciated, hopefully the guys behind the engine will notice more bug reports on this issue and act on it.
     
  18. Ardalan

    Ardalan

    Joined:
    Aug 16, 2013
    Posts:
    8
    Ostwind thanks for your time to test this, as far as I know the awake should start at the same time the splash screen ends, and the sound (which takes few frames to play) shouldn't be heard while splash screen is on (of course I am not a unity expert and started to use it since shiva3d engine died, but this should be the standard of any engine as far as I know).
    it would be great if you can file a bug report
     
  19. eskiroy

    eskiroy

    Joined:
    May 9, 2014
    Posts:
    10
    Hi I'm interested to know too... Did any of you managed to find a solution?
     
  20. seejay3061

    seejay3061

    Joined:
    Oct 21, 2013
    Posts:
    12
    I've run into this problem too. It is working as if the splash screen is a layer over the first scene on iOS. For my game this means that I can hear the title screen music while the splash screen is up and animation triggered in a script's start function on my title screen is already half way through when the splash screen disappears.
    This is working differently than it used to on iPhone apps in general. It used to be that's static image was always necessary at the start of an app while it loads and only disappeared after loading was complete. It seems to be working a little differently now. The solution could be in Xcode. If I learn of a solution I will come back here.
     
  21. seejay3061

    seejay3061

    Joined:
    Oct 21, 2013
    Posts:
    12
    Expanding on my previous note - I noticed in Xcode that the "Launch image" is actually a blank bluegray screen. Unity is definitely inserting a new view on top of our first scene that is handling their new logo after the bluegray launch image disappears. You can actually even press button on the underlying 1st scene if you have them.

    It looks like it is being controlled in "SplashScreen.mm" in Xcode. I am too much of a novice to really understand what I am looking at but modifying this probably would violate the unity license agreement anyway.

    On the plus side, this is likely on top of everyone's first scene for a specific amount of time regardless of device generation. Once we know exactly how long it is up (I couldn't tell in Xcode but someone else probably can), we can delay anything at app start up for that amount of time.

    In my case I return to my first scene after each game session so I'd ideally need to have a differentiation between app start up and returning to the scene from within the app. I'm not sure how to do that yet.

    Hope this helps
     
    Last edited: Jul 20, 2015
  22. Verfin

    Verfin

    Joined:
    Jun 2, 2013
    Posts:
    5
    I am having same difficulties on IPad 1 Mini, so it would seem to be Unity problem. Would be nice to hear from Unity staff about this.

    Has anybody submitted bug?
     
  23. dyy

    dyy

    Joined:
    Mar 15, 2014
    Posts:
    6
    I'm having the same problem. Any solution?
     
  24. Verfin

    Verfin

    Joined:
    Jun 2, 2013
    Posts:
    5
    I have submitted a bug report so waiting on that.
     
  25. Verfin

    Verfin

    Joined:
    Jun 2, 2013
    Posts:
    5
  26. MagicCard2005

    MagicCard2005

    Joined:
    Jul 26, 2015
    Posts:
    1
    Thank Verfin
    Now I just simply add this code at the first line of the function update()
    Code (CSharp):
    1. if(Application.isShowingSplashScreen) return;
     
    xavier-marleau likes this.
  27. juan-jo

    juan-jo

    Joined:
    May 15, 2010
    Posts:
    161
    Not bad as workaround, but this delay prevents normal operation of Start() and Awake(), for example, launch intro animations or music.
    Instead we are forced to transfer them to Update with a delay while "Application.isShowingSplashScreen".
    It is necessary that the startup screen disappears when Start() Update() are called.
     
  28. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    333
    I would just create an empty scene and load that at startup, then switch to the actual scene you want to start with after the splash screen has ended, using something like this:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.SceneManagement;
    3.  
    4. public class LoadNextSceneAfterSplash : MonoBehaviour
    5. {
    6.     public void Update()
    7.     {
    8.         // If done showing splash screen...
    9.         if (!Application.isShowingSplashScreen)
    10.         {
    11.             // ...Load the next scene in the build list
    12.             int nextScene = SceneManager.GetActiveScene().buildIndex + 1;
    13.             SceneManager.LoadScene(nextScene);
    14.         }
    15.     }
    16. }
    In fact, using some kind of empty scene to initialize your game at startup is a good idea in general. You could, for example, use this empty scene to load game resources while the splash screen is showing. Then load the next scene after loading is complete and/or user presses a button/splash screen is done, etc.
     
    Last edited: Aug 30, 2016
    juan-jo and Mycroft like this.
  29. juan-jo

    juan-jo

    Joined:
    May 15, 2010
    Posts:
    161
    Perhaps it is that the underlying idea behind this behavior. For ongoing projects or where you do not want or can not insert that pre-load scene, another way is to make a delayed pseudo-Start which effectively wait until the boot screen has been hidden:

    Code (CSharp):
    1. void Start ()
    2. {
    3.     StartCoroutine("StartAfterLoadScreen");
    4. }
    5.  
    6. private IEnumerator StartAfterLoadScreen ()
    7. {
    8.     while (Application.isShowingSplashScreen)
    9.         yield return null;
    10.  
    11.     // Your regular Start() stuff:
    12.     transform.parent.GetComponent<Animation>().Play();
    13. }
     
    Last edited: Aug 31, 2016
  30. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    333
    I think the easiest alternative to the empty scene technique would be to just pause the game until the splash screen is done, but this is not guaranteed to stop everything.

    Code (CSharp):
    1.     void Start()
    2.     {
    3.         StartCoroutine(PauseDuringSplashScreen());
    4.     }
    5.  
    6.     private IEnumerator PauseDuringSplashScreen()
    7.     {
    8.         Time.timeScale = 0f;
    9.  
    10.         while (Application.isShowingSplashScreen)
    11.             yield return null;
    12.  
    13.         Time.timeScale = 1f;
    14.     }
    This code should work because co-routines are not effected by the timescale (WaitForSeconds is however).
     
  31. berniebresslaw

    berniebresslaw

    Joined:
    Jan 2, 2013
    Posts:
    4
    A word of warning guys - I am using Application.isShowingSplashScreen in the way IsaiahKelly is describing and it occasionally reports it's showing the splash screen when it has long gone and will continue to misreport indefinitely....The result is my game soft-locks on boot. I have sent a bug report in for this. I am using Unity 5.4.1p2 and have seen it on various iOS versions including 10.
    I now have a timer backup and will be implementing a pixel check (as mentioned in other forum posts) :-(
     
  32. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    333
    @berniebresslaw Which implementation of mine are you using? I haven't tested any of this myself so I'm not exactly sure how Application.isShowingSplashScreen works exactly. However, to be safe I would just display a button at startup that the user has to press to begin the game (either unpauses or loads next scene). This should work fine because the user wont see it until the splash screen is gone. But I'm not sure if users could accidentally press it while the splash is still showing?