首页 > 解决方案 > SerializedField 中的 GameObject - OverRide - 全部应用:Prefab 不更新

问题描述

我在我的预制件中添加了一个脚本。然后我将我的预制件放入我的场景中,并将游戏对象拖放到检查器中的适当字段中。然后我单击 OverRides>>全部应用。(这很常见,我一直都这样做)但是,当游戏对象将被实例化时,我用于 Spawn Zone 的游戏对象将不适用于我的 Prefab。(场景中的预制件确实附加了空游戏对象,但项目面板中没有主预制件)我使用的方法与用于实例化子弹的方法相同,但由于某些未知原因,项目视图预制件会显示“无(游戏对象)”

这是代码:

[SerializeField]
private GameObject boss;
[SerializeField]
private float bossSpd;
[SerializeField]
private GameObject bossSpawnZone1; // This won't apply to my prefab in Project panel

private void Update()
{
    if(startBoss == true)//StartBoss occurs when a GameObject is touched by player on another script. Just OnTriggerEnter2D set var to true
    {
        GetTheBoss();
    }
}
void GetTheBoss()
{
    Instantiate(boss, bossSpawnZone1.transform.position, Quaternion.identity);
    startBoss = false;
}

我会包括图片,但我不知道如何在这里上传它们。以前从未使用过 IMG URL。但相信我,我将空的游戏对象(SpawnZone)插入到字段中。我还使用覆盖来应用所有。然而,生成区域字段仍然为空。

我试过的:

1)删除脚本并重新添加,然后再次填写字段。2) 将生成区域设为公共静态并尝试在与玩家有关的另一个脚本中使用 GameObject.Find("PirateSpawnZone")。3) 更改变量名并保存脚本。4) 重新启动 Unity / 完全重新启动计算机,然后打开 Unity 备份。

标签: c#unity3d

解决方案


预制件中不能有场景引用。这不可能。它仅适用于本身是存在于资产中的预制件的 GameObject 引用,或同一预制件层次结构中的引用。

但是存在一些解决方法

依赖注入

使用依赖注入(例如Zenject

ScriptableObject 引用

  1. 一个ScriptableObject,用于在场景开始时设置参考并ScriptableObject改为参考。

    [CreateAssetMenu(filename = "new GameObjectReference", menuName = "ScriptableObject/GameObjectReference")]
    public GameObjectReference : ScriptableObject
    {
        public GameObject value;
    }
    
  2. right click在 Assets → CreateScriptableObjectGameObjectReference

  3. 然后将您的脚本字段更改为

    [SerializeField] private GameObjectReference bossSpawnZone1;
    

    并且在您使用它的任何地方都使用它bossSpawnZone1.value

    这现在有效,因为 ScriptableObject 实例本身存在于资产中。

  4. 然后最后你需要bossSpawnZone1GameObject 上的 setter 组件,比如

    public GameObjectReferenceSetter : MonoBehaviour
    {
        [SerializeField] private GameObject scriptableAsset;
    
        private void Awake()
        {
            scriptableAsset.value = gameObject;
        }
    }
    

单例模式

只有设置器并进行public static参考(仅当整个场景/游戏中只有其中一个参考时才有效

public class SpawnZoneReference : MonoBehaviour
{
    public static GameObject instance;

    private void Awake ()
    {
        instance = gameObject;
    }
}

而在你的脚本中使用

Instantiate(boss, SpawnZoneReference.instance.transform.position, Quaternion.identity);

或仅使用某种类型非常相似,例如

public class BossSpawnZone : MonoBehaviour { }

GameObject你的脚本中做

bossSpawnZone1 = FindObjectOfType<BossSpawnZone>();

推荐阅读