【问题标题】:Unity, Spawn a prefab from another prefabUnity,从另一个预制件中生成预制件
【发布时间】:2017-05-12 05:49:36
【问题描述】:

我是 Unity 新手。我有一个不可见的 GameObject ,叫它 A,只有一个脚本,它多次实例化一个预制 B。我需要生成的 B 的克隆来引用回 A,我了解到为了使其工作,A 本身必须是一个预制件(如果我错了,请纠正我) 生成的 B 对象对鼠标点击做出反应并调用A 的方法。问题是在 A 的这个被调用方法中,A 本身的变量具有我不期望的值,例如在 Start() 中初始化为 0 并且从未使用过的某个变量的值为12. 似乎每个生成的对象 B 都有一个对其“自己的” A 的引用,并且 A 的变量具有随机值。我错过了什么?

【问题讨论】:

  • 您能否提供附加到 A GameObject 的脚本?

标签: unity3d


【解决方案1】:

为了让它工作,A 本身必须是一个预制件(如果我错了,请纠正我)

我假设您将预制件B 上脚本中的相关字段设置为A预制件,这不是您想要的。 A 根本不必是预制件

预制件是一个序列化的游戏对象,它包含特定的共享默认值,以便通过编辑器和编辑器/游戏内脚本轻松管理游戏对象。处理大量相似对象时使用预制件;除了一些修改的属性外,每个预制实例都将与另一个相似。这允许在一次单击中对预制实例进行大规模实例化修改。例如,将枪弹对象存储为预制件允许您通过单击修改所有枪弹的默认大小,同时允许在每个实例的基础上进行属性自定义。您可以将预制件视为可用于实例化 GameObject 的模板。

当通过A(以下简称ScriptA)上的脚本生成预制件B的实例时,只需在B的生成的实例上的脚本上设置必填字段(以下称为ScriptB)到ScriptAgameObject(或其他)字段,如下所示:

// ScriptA's method which spawns instances of prefab B
GameObject bInstance = Instantiate(prefabB);
ScriptB scriptOnBInstance = bInstance.GetComponent<ScriptB>();

scriptOnBInstance.referenceToAGameObject = this.gameObject;

【讨论】:

  • 起初我的 GameObject A 不是预制件,因为我只需要它的一个实例;我将它转换为预制件,因为我试图从编辑器(通过拖放)为预制件 B 提供对 A 的引用,假设这是为预制件 B 的克隆提供对 A 的引用的正确方法。但是以这种方式,在编辑预制件 B 并单击应用,我看到对 A 的引用丢失了,所以为了避免这种情况,我将 A 转换为预制件。现在我明白这完全没有意义,我可以通过编程方式为一个 GameObject 提供对另一个 GameObject 的引用。
  • @RaffaeleTasso 如果答案解决了您的问题,请接受它以将此问题标记为已回答,并帮助遇到相同问题的其他人轻松找到解决方案。
  • 作为另一个sn-p信息,预制件不会序列化(存储)包含对场景中对象的引用的任何字段值,因为该对象存在于其他场景中 无法保证。但是,对预制件的引用将被存储,因为它们被序列化到磁盘并且可以从整个项目的任何地方访问。因此,为什么在 B 的 prefab 中对 scene GameObject 实例 的引用丢失了,但对 prefab 的引用被保留了。
  • 感谢您的澄清,这是有道理的。在unity论坛上,对于同样的问题,有用户建议将对象A中的相关变量和方法标记为static。鉴于这两种解决方案都有效,您认为哪一种是最佳做法?
  • @RaffaeleTasso 我不想在这种情况下使用静态字段,因为它们会破坏实例化。如果您决定在一个场景中拥有多个 A 实例,则需要将静态字段设置为实例字段,并且几乎需要针对每次使用进行手动重构。但是,如果您使用实例字段,您只需将在消费者脚本中使用的 A 的引用更改为 A 的不同实例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多