如何从预制件中获取场景中游戏对象的引用
How can I grab a reference of a game-object in a scene from a prefab
目前我正在开发一个设备系统,它将游戏对象从列表中实例化到场景中,在此之前我没有使用实例化系统,只是让游戏对象始终在场景中保持活动状态。
现在通过实例化游戏对象(预制件),我 运行 在实例化它们时遇到了丢失引用的错误,我之前已经看过其他各种文章,例如这里的讨论:
不过,我正在寻找使用标签以外的其他方法,因为该系统可能会使用大量标签,随着时间的推移会降低游戏性能,有人知道将场景中的引用保存到预制件中的不同方法吗?
因此,由于这是一个新系统,我真的只是在寻找有关如何将场景游戏对象的引用保存到预制件中的建议,因为我的旧系统只是让游戏对象在场景中处于活动状态,而不是实际上实例化它们,我再次希望听到不同类型的方法,而不仅仅是使用标签。
我试图保存的参考是附加到我的预制件的脚本中的三个变换元素,它们如下
public Transform camPos;
public Transform aimLocation;
public Transform crosshairLocation;
目前我只是将场景中的游戏对象拖放到脚本中的 public 字段中
因为这将是一个主要系统,所以我不想为这个系统使用标签。但这绝对是一个有效的选择我只是在寻找其他方法将场景游戏对象的引用保存到预制件中将预制件实例化到场景中时,
感谢您抽出宝贵时间阅读,如有任何建议,我们将不胜感激!
有问题就问!
您可以不将场景引用保存在预制件中,原因很明显(如果将该预制件实例化到另一个场景中会发生什么情况?)。您的预制件需要在实例化后发现它需要的对象。我不太喜欢 Unity 中的标签系统(或任何其他使用字符串作为标识符的系统,错误空间太大)。我建议您采用以下三种方法中的任何一种:
将您需要的变换(凸轮位置、瞄准位置等)设为单例,如果每个变换都只有一个的话。您可以专门为每个脚本 class 制作一个脚本,使 class 成为一个单例,然后将其放在游戏对象上。然后,在你的预制件被实例化之后,你可以做这样的事情: camPos = CamPos.Instance.transform;
你可以阅读单例模式 here.
如果每个对象都不止一个,请将所有相关对象分组到一个层次结构中(也就是说,使它们都成为单个游戏对象的子对象)。例如,如果有很多角色并且每个角色都有一个单独的瞄准位置,您可以将瞄准位置设为角色游戏对象的子对象。然后,在您的预制件中(注意使预制件也成为同一根游戏对象的子对象),您可以按照以下方式做一些事情: camPos = transform.root.GetComponentInChildren<CamPos>().transform;
更好的是,您可以拥有一个引用所有组件的组件这样的对象,并将其中一个附加到根游戏对象。然后,你可以这样做:camPos = transform.root.GetComponent<ReferenceRepository>().CamPos;
- 实例化时初始化预制件。例如,假设您有一个实例化武器的玩家 class 并且已经有对 camPos 的引用。您可以这样做:
var weapon = Instantiate<Weapon>(myWeaponPrefab); weapon.CamPos = camPos;
但是请注意,当您以这种方式分配 public 字段时,它们只能在调用 Start
后访问。换句话说,它们将在 Awake
. 中不可用
就是说,无论如何,我不认为将目标位置和十字准线位置之类的东西分开是个好主意。您应该有一个 player/human/pawn class,并且 class 可以将此信息提供给需要它的其他对象。
目前我正在开发一个设备系统,它将游戏对象从列表中实例化到场景中,在此之前我没有使用实例化系统,只是让游戏对象始终在场景中保持活动状态。
现在通过实例化游戏对象(预制件),我 运行 在实例化它们时遇到了丢失引用的错误,我之前已经看过其他各种文章,例如这里的讨论:
不过,我正在寻找使用标签以外的其他方法,因为该系统可能会使用大量标签,随着时间的推移会降低游戏性能,有人知道将场景中的引用保存到预制件中的不同方法吗?
因此,由于这是一个新系统,我真的只是在寻找有关如何将场景游戏对象的引用保存到预制件中的建议,因为我的旧系统只是让游戏对象在场景中处于活动状态,而不是实际上实例化它们,我再次希望听到不同类型的方法,而不仅仅是使用标签。
我试图保存的参考是附加到我的预制件的脚本中的三个变换元素,它们如下
public Transform camPos;
public Transform aimLocation;
public Transform crosshairLocation;
目前我只是将场景中的游戏对象拖放到脚本中的 public 字段中
因为这将是一个主要系统,所以我不想为这个系统使用标签。但这绝对是一个有效的选择我只是在寻找其他方法将场景游戏对象的引用保存到预制件中将预制件实例化到场景中时,
感谢您抽出宝贵时间阅读,如有任何建议,我们将不胜感激!
有问题就问!
您可以不将场景引用保存在预制件中,原因很明显(如果将该预制件实例化到另一个场景中会发生什么情况?)。您的预制件需要在实例化后发现它需要的对象。我不太喜欢 Unity 中的标签系统(或任何其他使用字符串作为标识符的系统,错误空间太大)。我建议您采用以下三种方法中的任何一种:
将您需要的变换(凸轮位置、瞄准位置等)设为单例,如果每个变换都只有一个的话。您可以专门为每个脚本 class 制作一个脚本,使 class 成为一个单例,然后将其放在游戏对象上。然后,在你的预制件被实例化之后,你可以做这样的事情:
camPos = CamPos.Instance.transform;
你可以阅读单例模式 here.如果每个对象都不止一个,请将所有相关对象分组到一个层次结构中(也就是说,使它们都成为单个游戏对象的子对象)。例如,如果有很多角色并且每个角色都有一个单独的瞄准位置,您可以将瞄准位置设为角色游戏对象的子对象。然后,在您的预制件中(注意使预制件也成为同一根游戏对象的子对象),您可以按照以下方式做一些事情:
camPos = transform.root.GetComponentInChildren<CamPos>().transform;
更好的是,您可以拥有一个引用所有组件的组件这样的对象,并将其中一个附加到根游戏对象。然后,你可以这样做:camPos = transform.root.GetComponent<ReferenceRepository>().CamPos;
- 实例化时初始化预制件。例如,假设您有一个实例化武器的玩家 class 并且已经有对 camPos 的引用。您可以这样做:
var weapon = Instantiate<Weapon>(myWeaponPrefab); weapon.CamPos = camPos;
但是请注意,当您以这种方式分配 public 字段时,它们只能在调用Start
后访问。换句话说,它们将在Awake
. 中不可用
就是说,无论如何,我不认为将目标位置和十字准线位置之类的东西分开是个好主意。您应该有一个 player/human/pawn class,并且 class 可以将此信息提供给需要它的其他对象。