代码之家  ›  专栏  ›  技术社区  ›  Get Off My Lawn

Unity组件引用的是同一个游戏对象,而不是它本身

  •  0
  • Get Off My Lawn  · 技术社区  · 6 年前

    我有一个问题,当我一次实例化多个对象时 gameObject 在所有对象上引用相同的实例,而它们应该引用组件附加到的游戏对象。

    所以,我有这个 MonoBehaviour ,这是我代码的主要部分。当awake函数运行时,它应该创建每个函数的一个实例 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);
          });
        });
      }
    
    }
    

    我的 文件非常基本:

    [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)。但是,它们都引用了创建的第一个对象。。。。

    那么,是什么导致这些物品引用同一个游戏对象呢?

    从下图中可以看出,正在发生的是 Debug.Log

    Wrong References

    编辑

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

      public Bootstrap bootstrap {
        get { return _bootstrap; }
        set { _bootstrap = value; }
      }
    
    1 回复  |  直到 6 年前
        1
  •  -1
  •   Technivorous    6 年前
    var o = Instantiate(_gameObject, _position, Quaternion.identity);
    o.name = Random.Range(0, 1000).ToString();
    

    _gameObject 是您的对象引用,所有 var o 对象是此对象的克隆。这是实例化所需的行为。

    注意,如果 被摧毁, var o