Unity组件引用相同的gameObject而不是自身

时间:2018-10-19 16:19:28

标签: c# unity3d

我遇到的问题是,当我一次实例化多个对象时,gameObject引用所有对象上的相同实例,而它们应该引用组件所连接的gameObject。

因此,我有这个MonoBehaviour,这是我的代码的主要部分。当唤醒功能运行时,它应该为每个BootstrapMacro创建一个实例,这样我就不会覆盖.asset文件中的数据(在没有这部分的情况下会发生这种情况)。

然后在新实例中,设置对当前Bootstrap组件的引用。

public class Bootstrap : MonoBehaviour {

  [SerializeField] List<BootstrapMacro> macros;
  public List<BootstrapMacro> runtimeMacros = new List<BootstrapMacro>();

  void Awake() {
    // Create a runtime version of the macro so to not overwrite the original asset file
    macros.ForEach(macro => {
      if (macro != null) {
        var mac = Instantiate(macro);
        mac.events.ForEach(evt => {
          evt.bootstrap = this;
          evt.actions.ForEach(act => { act.bootstrap = this; });
        });
        runtimeMacros.Add(mac);
      }
    });
    RunMacro(e => e.OnObjectAwake());
  }

  void Start() { RunMacro(e => e.OnObjectStart()); }

  void RunMacro(System.Action<BootstrapEvent> action) {
    runtimeMacros.ForEach(macro => {
      if (macro == null) return;
      macro.events.ForEach(evt => {
        if (!evt.enabled) return;
        action.Invoke(evt);
      });
    });
  }

}

我的BootstrapMacro文件确实很基本:

[CreateAssetMenu(fileName = "Bootstrap Macro.asset", menuName = "Boostrap/Macro")]
public class BootstrapMacro : ScriptableObject {
  public List<Bootstrap.BootstrapEvent> events = new List<Bootstrap.BootstrapEvent>();
}

然后事件如下:

[BootstrapEvent(0)]
public class OnCreate : BootstrapEvent {
  public override void OnObjectStart() {
    Debug.Log(bootstrap.gameObject.name);
    Trigger();
  }
}

对此进行了扩展:

public class BootstrapEvent : ScriptableObject {

  Bootstrap _bootstrap;

  public Bootstrap bootstrap {
    get { return _bootstrap; }
    set { if (_bootstrap == null) _bootstrap = value; }
  }

  public virtual void OnObjectStart() { }
}

我正在实例化这样的对象:

var o = Instantiate(_gameObject, _position, Quaternion.identity);
o.name = Random.Range(0, 1000).ToString();

因此它正在创建对象并为其分配一个随机数。因此,在创建它时,我记录了上面显示的名称(代码块3)。但是,它们都引用创建的第一个对象。...

那么,是什么导致这些项目引用相同的gameObject?

从下图可以看到Debug.Log正在打印,即对象名称。如图所示,有多个对象名称被打印出来。每次销毁前一个对象时,都会将一个新的对象名称写入控制台。

Wrong References

编辑

所以,看来问题出在我的财产上。如果删除if(_bootstrap == null),则代码将按预期工作。如果我离开它,它将使用第一个创建的项目作为参考,直到它被销毁,然后下一个创建的项目成为参考。为什么?

  public Bootstrap bootstrap {
    get { return _bootstrap; }
    set { _bootstrap = value; }
  }

1 个答案:

答案 0 :(得分:-1)

var o = Instantiate(_gameObject, _position, Quaternion.identity);
o.name = Random.Range(0, 1000).ToString();

“那么,是什么导致这些项目引用相同的gameObject?”

_gameObject是您的对象引用,所有var o对象都是该对象的副本。这是带有实例化的理想行为。

请注意,如果_gameObject被销毁,var o将不再具有引用,并且您将崩溃。这就是我们使用预制件的原因。它们无法从场景中删除,因此您的引用不会为空。