Skip to main content
added 478 characters in body
Source Link
derHugo
  • 92.6k
  • 9
  • 94
  • 141

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 like

dependency injection

using dependency injection (e.g. Zenject)

or

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 → CreateScriptableObjectGameObjectReference

  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.

  1. 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>(); 

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 like using dependency injection (e.g. Zenject)

or

  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 → CreateScriptableObjectGameObjectReference

  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.

  1. 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; } } 

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 → CreateScriptableObjectGameObjectReference

  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.

  1. 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>(); 
Source Link
derHugo
  • 92.6k
  • 9
  • 94
  • 141

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 like using dependency injection (e.g. Zenject)

or

  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 → CreateScriptableObjectGameObjectReference

  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.

  1. 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; } }