unity-game-engine - 将预制件的脚本作为组件附加到另一个预制件

标签 unity-game-engine prefab

我有带有脚本 Player 的 Player 预制件

我还有带有 TouchMove 脚本的 GameController 预制件。 这是 TouchMove 代码:

public class TouchMove{
    [SerializeField] Player player;
    .....
}

所以 TouchMove 将玩家对象作为组件,我通过统一检查器附加它。 TouchMove 脚本负责玩家移动。这就是为什么它需要玩家对象。

此外,我有很多场景,每个场景都包含 GameController 和 Player 对象。 当我修改 GameController 或 Player 组件时,我希望更新所有场景中的所有游戏对象。这就是为什么我决定创建预制件:GameController 预制件和 Player 预制件。

在检查器中,我将 Player 预制件添加到 GameController 预制件中,因为 GameController 的 TouchMove 需要玩家对象。

enter image description here

但是之后当我运行游戏时,玩家脚本不再事件。我的意思是我无法移动游​​戏中的玩家。 (播放器脚本无法运行) 如果我将 Player 附加到 GameController 作为游戏对象(不是预制件或没有预制件)

所以,我的问题:

  1. 为什么如果我将其附加到预制件,玩家脚本就无法工作,而如果我将其作为游戏对象(没有预制件)附加,它就可以工作
  2. 是否可以按照我描述的方式链接两个预制件?

最佳答案

您遇到此问题的原因是播放器预制件和播放器预制件的特定实例 - 不是同一对象。它们都是 GameObject-s,并且都可以被引用。

在您的情况下,GameController 引用了玩家预制件,但场景中的玩家是一个新对象,它是通过克隆玩家预制件在场景启动时创建的。由于它仅在场景启动时创建 - 另一个预制件永远无法引用它。

要解决这个问题,您可以采取几种方法。

首先,将玩家和游戏 Controller 置于 1 个新对象下,例如将其命名为 GameManager。那么您将只有一个预制件 - 游戏管理器,其中包含玩家和 Controller 。

第二个选项是我通常使用的选项,是在加载时查找玩家对象。不要向玩家传递公共(public)参数,而是在唤醒时找到它,例如如下所示:

private Player player;
void  Awake() {
    player = FindObjectOfType<Player>();
    Assert.IsNotNull(player);
}

关于unity-game-engine - 将预制件的脚本作为组件附加到另一个预制件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70376949/

相关文章:

unity-game-engine - 将外部项目添加到统一解决方案

c# - 在根据我输入的数据实例化 Unity 预制件后,如何更改它的 Sprite ?

c# - 将预制件统一设置为另一个游戏对象的子对象

c# - 从 OnTriggerXXX 函数获取 ContactPoint2D/接触法线

c# - 如何在 Unity C# 中检查对象是否面向某个方向

c# - 在 Unity 中闪烁游戏对象

reactjs - 网页游戏开发中react/redux和unity的集成