C# 使用Unity编辑器中的AddComponent脚本撤消删除游戏对象(播放模式)

C# 使用Unity编辑器中的AddComponent脚本撤消删除游戏对象(播放模式),c#,unity3d,editor,undo-redo,C#,Unity3d,Editor,Undo Redo,我一直在努力回答一个非常具体的问题。我有一个简单的脚本,可以在运行时唤醒/销毁组件时创建/销毁组件: // Simple script that creates and destroys an AudioSource component in runtime. public class SimpleScript : MonoBehaviour { // Runtime AudioSource component to be used. private AudioSource source

我一直在努力回答一个非常具体的问题。我有一个简单的脚本,可以在运行时唤醒/销毁组件时创建/销毁组件:

// Simple script that creates and destroys an AudioSource component in runtime.
public class SimpleScript : MonoBehaviour {
  // Runtime AudioSource component to be used.
  private AudioSource source = null;

  void Awake() {
    source = gameObject.AddComponent<AudioSource>();
    source.hideFlags = HideFlags.HideAndDontSave;
  }

  void OnDestroy() {
    Destroy(source);
  }

  void Update() {
    // Do stuff with |source| . . .
  }
}
//在运行时创建和销毁音频源组件的简单脚本。
公共类简单描述:单一行为{
//要使用的运行时音频源组件。
私有音频源=空;
无效唤醒(){
source=gameObject.AddComponents附加到复活的游戏对象。更具体地说,一个被我之前的脚本用删除操作销毁,另一个是用新调用创建的。正如预期的那样,重复这样做会创建越来越多的泄漏组件

使用different to disable(?)序列化似乎对销毁组件没有任何好处,也没有尝试等等。我的理解是Unity将手动创建的组件视为的组件之一,因此注册销毁并在撤消脚本删除的同时撤消它

有没有关于如何绕过/避免这种奇怪的团结行为的建议


干杯!

你自己回答了你的问题,@anokta!
Awake()
方法创建音频源,即每次创建所属游戏对象时都会创建音频源。 现在,当您手动从层次结构视图中删除对象(即单击>删除等),然后撤消它时,您正在调用一个纯粹的编辑器机制来重新创建上次删除。这将基本上重新创建现有的对象(添加了
音频源的游戏对象
)。由于这是一个已创建的新对象,它将立即自动再次执行其
Awake()
方法

我相信您已经知道了这一点,并且可能正在寻找解决方法。在运行时手动删除编辑器中的对象是一个棘手的问题,使用它可以创建无数奇怪的行为

如果您真的想约束它,那么在其他位置(可能在全局管理器中)设置一个标志,该标志在调用
AddComponent();
时立即打开如何

void Awake() {
    if (globalManager.AsCreated != true)
    {
        source = gameObject.AddComponent<AudioSource>();
        source.hideFlags = HideFlags.HideAndDontSave;
        globalManager.AsCreated = true;
    }
}
void Awake(){
if(globalManager.AsCreated!=true)
{
source=gameObject.AddComponent();
source.hideFlags=hideFlags.hideAndOntSave;
globalManager.AsCreated=true;
}
}
其中,
globalManager
是某种全局管理器。通过这种方式,您可以在运行时删除对象(我仍然断言该对象会导致无休止的奇怪行为),并且仍然可以撤消所需的结果。
我希望这会有帮助!

如果你正在重新创建游戏对象,为什么不禁用并重新启用它呢?这里的问题是,你首先没有组件,也就是说,你必须在脚本中的某个地方创建它,以便启用/禁用它。:)遗憾的是,我同意了,也许让这种情况发生是可以的。我猜是全局的当涉及多个实例等时,标志解决方案可能会变得混乱。除此之外,我现在可以想到的另一个解决方案是在添加组件之前检查GetComponent。当然,这将限制我们在每个游戏对象中使用一个组件-IMO更不合适。:)