将预制件的脚本作为组件附加到另一个预制件
Attaching prefab's script to another prefab as a component
我有带有脚本 Player 的 Player 预制件
我还有带有脚本 TouchMove 的 GameController 预制件。
这是 TouchMove 代码:
public class TouchMove{
[SerializeField] Player player;
.....
}
所以 TouchMove 将播放器对象作为一个组件,我通过 unity inspector 附加了它。
TouchMove 脚本负责玩家移动。这就是为什么它需要玩家对象。
我还有很多场景,每个场景都包含 GameController 和 Player 对象。
当我修改 GameController 或 Player 组件时,我希望更新所有场景中的所有游戏对象。这就是我决定创建预制件的原因:GameController 预制件和 Player 预制件。
在检查器中,我将 Player 预制件添加到 GameController 预制件中,因为 GameController 的 TouchMove 需要玩家对象。
但在它之后 当我 运行 游戏时玩家脚本变得不活跃 。我的意思是我无法在游戏中移动玩家。 (播放器脚本无法正常工作)
如果我将 Player 附加到 GameController 作为游戏对象(不是预制件或没有预制件)
,这个问题就会解决
所以,我的问题:
- 为什么如果我用预制件附加播放器脚本就不能工作,而如果我像游戏对象一样附加它(没有预制件)它就可以工作
- 是否可以按照我描述的方式link两个预制件?
您遇到此问题的原因是播放器预制件和播放器预制件的特定实例 - 不是同一个对象。都是GameObject-s,都可以引用
在你的例子中,GameController 引用了一个玩家预制件,但场景中的玩家是一个新对象,它是在场景开始时通过克隆玩家预制件创建的。由于它仅在场景开始时创建 - 另一个预制件永远无法引用它。
要解决这个问题,您可以采取几种方法。
First,玩家和游戏控制器都在 1 个新对象下,例如将其称为 GameManager。那么你将只有一个预制件 - 游戏管理器,其中包含玩家和控制器。
第二个选项,我通常使用的选项是在加载时查找播放器对象。不要向 player 传递一个 public 参数,而是在唤醒时找到它,例如:
private Player player;
void Awake() {
player = FindObjectOfType<Player>();
Assert.IsNotNull(player);
}
预制件需要在场景中存在(实例化)才能运行,您正在尝试做的是可编写脚本的对象的工作流。
不要通过检查器从项目目录附加源预制件,而是尝试在场景中查找预制件的现有实例(在运行时)。
private void Awake()
{
player = FindObjectOfType<Player>();
}
我有带有脚本 Player 的 Player 预制件
我还有带有脚本 TouchMove 的 GameController 预制件。 这是 TouchMove 代码:
public class TouchMove{
[SerializeField] Player player;
.....
}
所以 TouchMove 将播放器对象作为一个组件,我通过 unity inspector 附加了它。 TouchMove 脚本负责玩家移动。这就是为什么它需要玩家对象。
我还有很多场景,每个场景都包含 GameController 和 Player 对象。 当我修改 GameController 或 Player 组件时,我希望更新所有场景中的所有游戏对象。这就是我决定创建预制件的原因:GameController 预制件和 Player 预制件。
在检查器中,我将 Player 预制件添加到 GameController 预制件中,因为 GameController 的 TouchMove 需要玩家对象。
但在它之后 当我 运行 游戏时玩家脚本变得不活跃 。我的意思是我无法在游戏中移动玩家。 (播放器脚本无法正常工作) 如果我将 Player 附加到 GameController 作为游戏对象(不是预制件或没有预制件)
,这个问题就会解决所以,我的问题:
- 为什么如果我用预制件附加播放器脚本就不能工作,而如果我像游戏对象一样附加它(没有预制件)它就可以工作
- 是否可以按照我描述的方式link两个预制件?
您遇到此问题的原因是播放器预制件和播放器预制件的特定实例 - 不是同一个对象。都是GameObject-s,都可以引用
在你的例子中,GameController 引用了一个玩家预制件,但场景中的玩家是一个新对象,它是在场景开始时通过克隆玩家预制件创建的。由于它仅在场景开始时创建 - 另一个预制件永远无法引用它。
要解决这个问题,您可以采取几种方法。
First,玩家和游戏控制器都在 1 个新对象下,例如将其称为 GameManager。那么你将只有一个预制件 - 游戏管理器,其中包含玩家和控制器。
第二个选项,我通常使用的选项是在加载时查找播放器对象。不要向 player 传递一个 public 参数,而是在唤醒时找到它,例如:
private Player player;
void Awake() {
player = FindObjectOfType<Player>();
Assert.IsNotNull(player);
}
预制件需要在场景中存在(实例化)才能运行,您正在尝试做的是可编写脚本的对象的工作流。
不要通过检查器从项目目录附加源预制件,而是尝试在场景中查找预制件的现有实例(在运行时)。
private void Awake()
{
player = FindObjectOfType<Player>();
}