美文网首页
[RS] Timeline踩坑(2):The object ha

[RS] Timeline踩坑(2):The object ha

作者: _Walker__ | 来源:发表于2022-07-28 10:28 被阅读0次

    记录环境

    • Unity 2021.3.4f1
    • Timeline 1.6.4

    问题描述

      首先说明下,这个报错不是Unity直接抛出的,它就是我们写的轨道代码里,访问了一个已经被Destroy的对象。但是,导致这个报错出现,不是因为我们用法不合理!!!
      我们项目在切换情景的时候,会将当前情景的资源“全部卸载”,其中就包含TML及其控制的角色。
      我们在主城切换到副本的时候,爆出来这个MissingReferenceException的问题。检查后发现项目中资源释放的逻辑没有问题,轨道里的代码也符合制作规范。

    统一资源释放流程(部分):
    1.先停止所有正在播放的TML
    2.释放/销毁资源,这里包含TML、角色等(这一步的顺序不重要)

    轨道实现的规范(部分):
    【轨道还原】在离开Clip、退出或销毁Track等时机时,要尽量还原被控角色的状态

      轨道还原是因为我们TML主要用在战斗中做技能表演,每个技能释放完毕后,需要角色还原到自己的出场站位,所以大部分轨道都需要做还原这个处理。
      基于TML的设定,我们在做资源释放时,就要保证上面的顺序。因为TML结束的时候,仍然会访问角色的对象,故TML需要先停止。

    原因说明

      经过进一步打Log测试,我发现TML的停止跟Playable资源的停止并不是同步进行的。

    测试得到一个结论:

    PlayableDirector.Stop()与PlayerBehaviour.OnPlayableDestroy()是在同一帧执行,但不是同步执行,OnPlayableDestroy会晚一些。

    测试的Log流程(下面这些全部在同一个Update帧输出):

    1. PlayableDirector.Stop()【主动停止TML】
    2. TimelineCtrl.OnDestroy()【停止TML后,销毁角色跟TML】
    3. Update() 开始【停止TML时,做了个标记让某个脚本的Update在第一行输出Log】
    4. Update() 结束【同上,在最后一行输出Log】
    5. PlayerBehaviour.OnPlayableDestroy()【Unity内部在UpdateDirectorUpdateRegistrator::Forward调过来】
    6. Frame End【停止TML时,开了个协程在WaitForEndOfFrame之后输出Log】
    // OnPlayableDestroy的执行堆栈
    MoleTimeline.MoleStateMixer:OnPlayableDestroy (UnityEngine.Playables.Playable) 
    ...
    0x00007ff7ae5e01d4 (Unity) ScriptingInvocation::Invoke
    0x00007ff7ae56f5c0 (Unity) PlayableMethods::InvokePlayableDestroy
    0x00007ff7ae562112 (Unity) Playable::DeallocateResources
    0x00007ff7ae568862 (Unity) PlayableGraph::DestroyPendingPlayables
    0x00007ff7ae568387 (Unity) PlayableGraph::Destroy
    0x00007ff7ae56c876 (Unity) DirectorManager::ProcessPlayStateChanges
    0x00007ff7ae56a657 (Unity) `DirectorManager::InitializeClass'::`2'::UpdateDirectorUpdateRegistrator::Forward
    0x00007ff7ae2a437c (Unity) ExecutePlayerLoop
    0x00007ff7ae2a4453 (Unity) ExecutePlayerLoop
    0x00007ff7ae2aa099 (Unity) PlayerLoop
    

    推测: Unity内部维护了一个Playable的列表,并在Update里每帧去做清理,PlayableDirector.Stop只做了一个可销毁的标记。

    解决方案

      暂时没找到比较好的解决方案,只是在每个Track的代码里,自己判断要用的资源是否合法。

    相关文章

      网友评论

          本文标题:[RS] Timeline踩坑(2):The object ha

          本文链接:https://www.haomeiwen.com/subject/ivntwrtx.html