我遇到的问题是,当我一次实例化多个对象时,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
正在打印,即对象名称。如图所示,有多个对象名称被打印出来。每次销毁前一个对象时,都会将一个新的对象名称写入控制台。
所以,看来问题出在我的财产上。如果删除if(_bootstrap == null)
,则代码将按预期工作。如果我离开它,它将使用第一个创建的项目作为参考,直到它被销毁,然后下一个创建的项目成为参考。为什么?
public Bootstrap bootstrap {
get { return _bootstrap; }
set { _bootstrap = value; }
}
答案 0 :(得分:-1)
var o = Instantiate(_gameObject, _position, Quaternion.identity);
o.name = Random.Range(0, 1000).ToString();
“那么,是什么导致这些项目引用相同的gameObject?”
_gameObject
是您的对象引用,所有var o
对象都是该对象的副本。这是带有实例化的理想行为。
请注意,如果_gameObject
被销毁,var o
将不再具有引用,并且您将崩溃。这就是我们使用预制件的原因。它们无法从场景中删除,因此您的引用不会为空。