0
votes

I added a script to my prefab. Then I put my prefab into my scene and drag/dropped the GameObjects into the appropriate fields within the inspector. I then clicked OverRides>>Apply All. (Which is common and I do this all of the time) However, the game object I'm using for the Spawn Zone when the Game Object will be Instantiated will not apply to my Prefab. (The Prefab in the scene does have the Empty Game Object attached but not the main Prefab in the Project panel) I'm using the same method that I use for Instantiating bullets but for some unknown reason the Project view prefab will say "None(GameObject)"

Here's the code:

[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;
}

I would include pics but I don't know how to upload them in here. Never used the IMG URL before. But trust me, I inserted the empty gameobject(SpawnZone) into the field. I also used the override to apply all. Yet the spawn zone field remains empty.

What I've tried:

1) Removing the script and re-adding it then filling the fields again. 2) Made the spawn zone public static and tried using GameObject.Find("PirateSpawnZone") in another script pertaining to the player. 3) Changing the variable name and saving the script. 4) Restarting Unity / Restarted computer completely then open Unity back up.

1
@derHugo I put the prefab into the scene and I inserted the fields on that prefab. Then I applied the update. All fields are filled except the spawnzone. I use this technique all the time so I'm confused as to why all of a sudden it is refusing to accept the gameobject upon Override>>Apply AllAntonioTorro

1 Answers

1
votes

You can not have Scene references in a prefab. It is not possible. It only works for GameObject reference that are themselves a prefab living in the asset or references within one and the same prefab hierarchy.

However some workarounds exist

dependency injection

using dependency injection (e.g. Zenject)

ScriptableObject references

  1. a ScriptableObject for setting the reference on scene start and referencing the ScriptableObject instead.

    [CreateAssetMenu(filename = "new GameObjectReference", menuName = "ScriptableObject/GameObjectReference")]
    public GameObjectReference : ScriptableObject
    {
        public GameObject value;
    }
    
  2. Create an Asset by right click in the Assets → Create → ScriptableObject → GameObjectReference

  3. Then change your script field to

    [SerializeField] private GameObjectReference bossSpawnZone1;
    

    and everywhere where you use it use bossSpawnZone1.value instead.

    This works now since the ScriptableObject instance itself lives in the Assets.

  4. Then finally you need the setter component on the bossSpawnZone1 GameObject like

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

Singleton pattern

having only the setter and making a public static reference (only works if there is only exactly one of those reference in the entire scene/game

public class SpawnZoneReference : MonoBehaviour
{
    public static GameObject instance;

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

And in your script instead use

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

Or very similar using only a certain type like

public class BossSpawnZone : MonoBehaviour { }

On the GameObject and in your script do

bossSpawnZone1 = FindObjectOfType<BossSpawnZone>();