예제 #1
0
    /// <summary>
    /// This method actually does the transition. It is run in a coroutine and therefore needs to do
    /// yield returns to play an animation or do another progress over time. When this method returns
    /// the transition is expected to be finished.
    /// </summary>
    /// <returns>
    /// A <see cref="IEnumerator"/> for showing the transition status. Use yield return statements to keep
    /// the transition running, otherwise simply end the method to stop the transition.
    /// </returns>
    protected virtual IEnumerator DoTransition()
    {
        // make sure the transition doesn't get lost when switching the level.
        DontDestroyOnLoad(gameObject);
#if !UNITY_3_5
        AsyncOperation asyncOperation = null;
        if (prefetchLevel)
        {
            state = SMTransitionState.Prefetch;
            SendMessage("SMBeforeTransitionPrefetch", this, SendMessageOptions.DontRequireReceiver);
            yield return(0);            // wait one frame

            SendMessage("SMOnTransitionPrefetch", this, SendMessageOptions.DontRequireReceiver);

            var loadLevel = DoLoadLevel();
            while (loadLevel.MoveNext())
            {
                var current = loadLevel.Current;
                if (asyncOperation == null)                   // try to find the actual level loading operation
                {
                    asyncOperation = current as AsyncOperation;
                    if (asyncOperation != null)
                    {
                        // hold on level switch until the transition is in hold state.
                        asyncOperation.allowSceneActivation = false;
                    }
                }
                yield return(0);
            }
        }
#endif
        state = SMTransitionState.Out;
        SendMessage("SMBeforeTransitionOut", this, SendMessageOptions.DontRequireReceiver);
        Prepare();
        SendMessage("SMOnTransitionOut", this, SendMessageOptions.DontRequireReceiver);
        float time = 0;

        while (Process(time))
        {
            time += DeltaTime * 2f;
            // wait for the next frame
            yield return(0);
        }

        SendMessage("SMAfterTransitionOut", this, SendMessageOptions.DontRequireReceiver);
        // wait another frame...
        yield return(0);

        StageMgr.ExcuteBeginLoadEvent();
        Resources.UnloadUnusedAssets();

        state = SMTransitionState.Hold;
        SendMessage("SMBeforeTransitionHold", this, SendMessageOptions.DontRequireReceiver);
        SendMessage("SMOnTransitionHold", this, SendMessageOptions.DontRequireReceiver);

        // wait another frame...
        yield return(0);

#if !UNITY_3_5
        if (!prefetchLevel)
        {
#endif
        // level is not prefetched, load it right now.
        var loadLevel = DoLoadLevel();
        while (loadLevel.MoveNext())
        {
            yield return(loadLevel.Current);
        }
#if !UNITY_3_5
    }

    else
    {
        if (asyncOperation != null)                   // this should always be true, but you never know...
        // level was prefetched, so activate level switch now.
        {
            asyncOperation.allowSceneActivation = true;
            ScenePreloader.Instance.AllowEnter();
        }
    }
#endif
        while (true)
        {
            if (StageMgr.Scene_name.Equals(Application.loadedLevelName))
            {
                break;
            }
            yield return(0);
        }

        System.GC.Collect();

        StageMgr.ExcuteLoadedEvent();
        SendMessage("SMAfterTransitionHold", this, SendMessageOptions.DontRequireReceiver);
        // wait another frame...
        yield return(0);

        //LoadingScene.Instance.EnterScene(asyncOperation);
        state = SMTransitionState.In;
        SendMessage("SMBeforeTransitionIn", this, SendMessageOptions.DontRequireReceiver);
        Prepare();
        SendMessage("SMOnTransitionIn", this, SendMessageOptions.DontRequireReceiver);
        time = 0;

        while (Process(time))
        {
            time += DeltaTime;
            // wait for the next frame
            yield return(0);
        }

        SendMessage("SMAfterTransitionIn", this, SendMessageOptions.DontRequireReceiver);
        // wait another frame...
        yield return(0);

        Destroy(gameObject);

        StageMgr.ExcuteAllLoadedEvent();
    }