返回

一不小心把对象销毁了?Unity Timeline 踩坑记(二)

见解分享

在 Unity Timeline 中避免“对象已被销毁”的报错

Unity Timeline 是一个强大的工具,可用于创建和管理动画和游戏玩法。然而,如果不小心,您可能会遇到一个常见的错误:“对象已被销毁,但您仍尝试访问它”。本文将探讨这个错误的来龙去脉,并指导您如何避免踩雷。

错误的本质

此错误不是由 Unity 直接抛出的,而是由您编写的轨道代码访问了一个已被销毁的对象。简而言之,就是对象消失了,代码仍在访问它。

踩坑场景

让我们模拟一下这个错误的发生场景:

  1. 创建一个新的 Unity 项目并导入 Timeline 包。
  2. 创建一个新场景,并添加一个名为“Player”的空游戏对象。
  3. 为“Player”对象添加一个 Timeline 组件。
  4. 创建一个轨道并将其命名为“Position”。
  5. 在“Position”轨道上创建一个剪辑并将其命名为“MoveForward”。
  6. 在“MoveForward”剪辑中,添加一个“Translate”轨道。
  7. 在“Translate”轨道上,设置一条平滑的平移曲线,将“Player”对象从原点沿 X 轴移动 10 个单位。
  8. 运行场景。

恭喜,您踩坑了!控制台会输出以下错误:

对象已被销毁,但您仍尝试访问它。
UnityEngine.GameObject:GetComponent[TimelineAsset]()
TimelineAsset:GetOutputTrack(GameObject, String, Int32, TimelineClip, Int32)
TimelineTrack:GetOutputTracks()
TimelineTrackAsset:GetOutputTracks()

错误根源

问题的根源在于轨道代码中。我们使用 GetComponent 函数从“Player”对象获取 TimelineAsset 组件。但在剪辑播放完成后,“Player”对象将被销毁。

这意味着当我们尝试在剪辑结束后访问 TimelineAsset 组件时,该组件已不存在,从而引发错误。

避坑之道

避免此错误的方法很简单:在剪辑结束后检查“Player”对象是否已被销毁。如果是,则不要访问 TimelineAsset 组件。

void OnFinish()
{
    if (Player != null)
    {
        // 访问 TimelineAsset 组件
    }
}

总结

在 Unity 中开发时,密切关注对象的生命周期至关重要。如果不小心销毁了一个对象,而代码仍在访问它,则会出现各种问题。因此,在编写代码时,请务必谨慎操作,避免踩坑。

常见问题解答

  1. 为什么会在剪辑结束后销毁“Player”对象?

    为了释放资源和优化性能,Unity 通常会在动画结束后自动销毁游戏对象。

  2. 我可以使用 DontDestroyOnLoad 脚本阻止“Player”对象被销毁吗?

    可以,但强烈建议不要这样做。这可能会导致内存泄漏和其他问题。

  3. 还有其他方法可以避免此错误吗?

    是的,您可以使用 Unity Event 系统或消息传递来在剪辑结束时安全地访问组件。

  4. 这个错误只会在 Timeline 中发生吗?

    不,它也可能发生在其他情况下,例如当您尝试访问已销毁对象上的组件时。

  5. 如何调试此错误?

    使用调试器设置断点,并在触发错误时检查变量的值。您还可以使用 GameObject.activeSelf 属性来检查对象是否已被销毁。