exdev / ex2d-dev

2D framework and pipeline for Unity3D
ex-dev.com/ex2d
GNU General Public License v3.0
6 stars 3 forks source link

采用 ex2DRenderer.InsertLayer 方法动态加载场景时,出现错误信息,并且加载Layer不能正常显示 #50

Closed jwu closed 11 years ago

jwu commented 11 years ago

重现方法:

得sheeptap 2最新版本,运行 Launch 场景。

制作思路:

在数羊项目中,场景和场景之间的 loading 画面是保存在一份 layer 中。loading画面本身也是 sprite 组合出来的动态GO。为了能够让 sprite 在场景和场景间正确切换,实际操作方法是:

进入 Launch, mask_layer 已经加入 Launch 场景的 2D Renderer 中。之后 Load 场景1,

Fade In Mask Layer (0.5秒) -> Application.LoadScene("场景1") -> yield 直到取得"场景1" 的 2D Renderer -> 2D Renderer.InsertLayer ( maskLayer ) -> Fade Out Mask Layer (0.5秒) -> 调用场景运行函数 Run() 并开始运行场景。

报错如下:

错误1: Assert Failed! Sprite should remove from last layer before add to new one UnityEngine.Debug:LogError(Object, Object) exDebug:Assert(Boolean, String, Boolean, Object) (at Assets/ex2D/Runtime/Utilities/exUtility.cs:70) exLayeredSprite:set_layer(exLayer) (at Assets/ex2D/Runtime/Components/Internal/exLayeredSprite.cs:88) exLayer:DoAddSprite(exLayeredSprite, Boolean) (at Assets/ex2D/Runtime/Components/exLayer.cs:889) exLayer:GenerateMeshes() (at Assets/ex2D/Runtime/Components/exLayer.cs:463) ex2DRenderer:InsertLayer(Int32, exLayer) (at Assets/ex2D/Runtime/Components/ex2DRenderer.cs:212) Game:ResetCamera() (at Assets/Game/Scripts/Game/Game.cs:96) Game:Awake() (at Assets/Game/Scripts/Game/Game.cs:62)

错误2: Assert Failed! Can't add duplicated sprite UnityEngine.Debug:LogError(Object, Object) exDebug:Assert(Boolean, String, Boolean, Object) (at Assets/ex2D/Runtime/Utilities/exUtility.cs:70) exLayer:AddToMesh(exLayeredSprite, exMesh) (at Assets/ex2D/Runtime/Components/exLayer.cs:913) exLayer:DoAddSprite(exLayeredSprite, Boolean) (at Assets/ex2D/Runtime/Components/exLayer.cs:905) exLayer:GenerateMeshes() (at Assets/ex2D/Runtime/Components/exLayer.cs:463) ex2DRenderer:InsertLayer(Int32, exLayer) (at Assets/ex2D/Runtime/Components/ex2DRenderer.cs:212) Game:ResetCamera() (at Assets/Game/Scripts/Game/Game.cs:96) Game:Awake() (at Assets/Game/Scripts/Game/Game.cs:62)

错误3: Assert Failed! UnityEngine.Debug:LogError(Object, Object) exDebug:Assert(Boolean, String, Boolean, Object) (at Assets/ex2D/Runtime/Utilities/exUtility.cs:70) exLayer:AddIndices(exMesh, exLayeredSprite) (at Assets/ex2D/Runtime/Components/exLayer.cs:985) exLayer:AddToMesh(exLayeredSprite, exMesh) (at Assets/ex2D/Runtime/Components/exLayer.cs:921) exLayer:DoAddSprite(exLayeredSprite, Boolean) (at Assets/ex2D/Runtime/Components/exLayer.cs:905) exLayer:GenerateMeshes() (at Assets/ex2D/Runtime/Components/exLayer.cs:463) ex2DRenderer:InsertLayer(Int32, exLayer) (at Assets/ex2D/Runtime/Components/ex2DRenderer.cs:212) Game:ResetCamera() (at Assets/Game/Scripts/Game/Game.cs:96) Game:Awake() (at Assets/Game/Scripts/Game/Game.cs:62)

jareguo commented 11 years ago

已修复

jwu commented 11 years ago

InsertLayer 这个函数本身已经没有问题了。但是目前的问题是游戏第一帧进行Insert的时候会发现有部分layer 比 loading layer 先显现的情况。

我觉得这个问题并不那么简单。这里我贴一下整个 loading 的处理代码:

    // ------------------------------------------------------------------ 
    // Desc: 
    // ------------------------------------------------------------------ 

    IEnumerator LoadStage_CO ( string _sceneName ) {
        // fade in loading layer
        yield return StartCoroutine (FadeLoading(true,0.2f));

        // load the stage
        // Application.LoadLevel(_sceneName); // DISABLE
        yield return Application.LoadLevelAsync(_sceneName);
        yield return Resources.UnloadUnusedAssets();

        // wait until stage initialized
        while ( Stage.initialized == false ) {
            yield return 0;
        }
        System.GC.Collect();

        // fade out loading layer
        ResetCamera ();
        yield return StartCoroutine (FadeLoading(false,0.2f));

        // run the stage
        Stage.inst.Run ();
    }

在上面这段代码中,ResetCamera 做的事情就是 InsertLayer( 0, maskLayer ). 这里可以看到 LoadLevel 以后,会调用 Awake, 所以整个处理过程会在 InsertLayer 之前,这导致了开始画面第一帧的闪现。

jwu commented 11 years ago

通过将 InsertLayer 的调用放在 Scene 中 GO 的 Awake 里可以解决。