【问题标题】:Unity3D - Disabled GameObject scripts losing stateUnity3D - 禁用的游戏对象脚本丢失状态
【发布时间】:2017-03-18 17:49:54
【问题描述】:

我在一个游戏对象(此处简化)上有一个脚本组件,它在创建时被禁用,使用 testObject.setActive(false)

using UnityEngine;

public TestObject : MonoBehaviour {
    public int testValue = 5;

    void Start() {
        testValue = 0;
    }

    public int GetTestValue() {
        return testValue;
    }
}

在禁用之前,GetTestValue 的返回是 0。一旦我重新启用对象,返回是 5。

Unity 文档说:

使游戏对象处于非活动状态将禁用所有组件...您附加到游戏对象的任何脚本将不再调用 Update()...

但是,组件的行为向我表明,脚本生成的 MonoBehaviour 并不是真正“禁用”,而是被破坏了。如果只有 Update() 停止被调用,那如何解释状态丢失?

这里的根本问题是:在不销毁脚本的情况下暂时禁用脚本的预期方法是什么?

【问题讨论】:

  • 肯定比你说的要多。如果设置为 false,则引擎不会调用所有 Unity 方法(Update、LateUpdate、Collision...),但仍可以从其他地方调用公共方法并影响脚本的状态。例如,您仍然可以从另一个脚本调用 GetTestValue,即使它处于非活动状态。设置 on 和 off 不会影响变量的内容,也不会破坏实例。因此,要么您实际上是在其他地方销毁并创建一个新对象,要么您正在查看 2 个不同的对象,或者您正在其他地方重置该值。
  • @Everts:你说得对,还有“更多”。我应该明确说明在实例化之后立即发生停用。

标签: unity3d gameobject


【解决方案1】:

实际上发生的是Start() 函数在对象的生命周期中只被调用一次。所以一开始它被调用并将值设置为0。但是当你禁用它并重新激活它时,它不会被调用。

这并没有改变这样一个事实,即即使在停用和重新激活脚本之后,您的值应该仍然是相同的(正如我们在 cmets 部分中发现的那样)。

实现这项工作的一种方法是使用OnEnable(),每次脚本被setActive 时都会调用它。 More info on OnEnable:

当对象启用并处于活动状态时调用此函数。

所以在你的脚本中你会有:

private void OnEnable()
{
    testValue = 0;
}

如果您知道此对象将被多次激活和停用,并且每次发生这种情况时您绝对需要做一些事情。


这让我想到了我的第二点和我的建议:

不要在将被停用和重新激活的脚本上保留重要值。

将重要信息保存在永远不会被停用的脚本中,这样您就可以始终确定值始终是正确的。因此,您不必总是重新生成正确的值并每次检查它是否真的是您获得的好值。

【讨论】:

  • 在对象的生命周期中只调用一次 - 很明显,对象不能在停用时被销毁,因为正如你所说,Start() 只调用一次.这并不能解释为什么对象会失去其内部状态。
  • @frog 它并没有失去它的价值,你只是用那行覆盖它public int testValue = 5;
  • 不可能的。将 5 分配给 testValue 是在对象构造函数中完成的——这是编译器从初始化语法自动生成的。构造函数,如 Start(),在对象的生命周期中只调用一次。因此 testValue 不能永远被字段初始化器覆盖。
  • @frog 所以我一直在尝试重新创建您的问题,但是当我禁用我的对象并重新激活它时 testValue 仍然是 0,您确定没有其他东西可以重置您的值吗?
  • 感谢您的意见,@CNuts -- 我在最初的问题中没有提到我在Instantiate() 之后立即拨打了setActive(false)。请参阅下面的答案。
【解决方案2】:

事实证明,问题在于竞争条件。在 Start() 完成之前,TestObject 被停用,这阻止了对象被正确初始化。通过将初始化代码移至 Awake(),对象在停用之前正确设置了其状态。

【讨论】:

    【解决方案3】:

    我有相反的情况..我试图在 Awake() 中设置一个动画参数并立即停用。参数值没有改变。但是如果我把它放在 Start() 中,值就设置好了。

    【讨论】:

    • 如果您还有其他问题,请点击 按钮进行提问。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多