- Home /
The question is answered, right answer was accepted
PrefabHell - How to have scripts of prefabs instances reference the variables of the prefab instance they're attached to?
How to get script on prefab instance to reference/use variables on instance, rather than referencing the uninstantiated one in the project folder.
Old Question : Prefab Hell - Script is not finding the instantiated prefab variables- only the uninstantiated version's variables
I'm attempting to make a super simple 10 source AudioManager. I've tried multiple attempts at this, but am getting the EXACT same problem.
My script is grabbing the uninstantiated prefab's variables, rather than the instantiated prefab variables.
Specifically, if I have a prefab w/ a List myAudioSources - and I grab myAudioSources[0], it'll grab the uninstantiated prefab's ref [0], & give me a STUPID "Audio source disabled error". The one it's grabbing isn't instantiated, so OFC it's disabled, but hell if you'll know that, as it will HAPPILY act like it's grabbing the instantiated one. It ISN'T.
Alternatively, if I create an array, because I'm aware it's b/sing me, AudioSources[] myAudioSources. Then in Awake(){ myAudioSources = new AudioSource[10] - then create array references}--- It will do the same b/s, and attempt to grab the non-instantiated array's references. So myAudioSources[0] - returns a ref error, despite the instantiated prefab having a reference there.
So, my question is simple, how do I grab the instantiated prefab's references?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AudioManager : MonoBehaviour
{
public List<AudioClip> UIClips = new List<AudioClip>();
// UI Clip Index List
// 0 = BTN_Hover
// 1 = BTN_Click
// 2 = BTN_Fail
// 3 = BTN_StartGame
// 4 =
public GameObject[] myAudioSources;
public List<int> myAudioSourceListIndex = new List<int>();
// Start is called before the first frame update
void Awake()
{
InitAudioSources();
}
public void InitAudioSources()
{
myAudioSources = new GameObject[9];
for (int i = 0; i < myAudioSources.Length; i++)
{
GameObject io = new GameObject();
io.AddComponent<AudioSource>();
myAudioSources[i] = io;
}
}
public int FindAvailAudioSourceIndex()
{
for (int i = 0; i < myAudioSources.Length; i++)
{
if(myAudioSources[i].GetComponent<AudioSource>().isPlaying == false)
{
return i;
}
}
Debug.Log("FindAvailAudioSourceIndex==FAILED");
return 0;
}
public void CallHoverSfx()
{
int a = 0;
//int a = FindAvailAudioSourceIndex();
myAudioSources[a].GetComponent<AudioSource>().enabled = true;
myAudioSources[a].GetComponent<AudioSource>().clip = UIClips[0];
myAudioSources[a].GetComponent<AudioSource>().Play();
Debug.Log("index = " + a);
Debug.Log(myAudioSources[a].GetComponent<AudioSource>().enabled);
}
}
Ok, this time for sure >.> I just realized the problem. As should be obvious, my CallHoverSfx() function- is for a button.
Turns out, I thought the button was referencing the prefab instance, but it's referencing the uninstantiated prefab.
I chose from the list, rather than drag & dropping. Visually identical, while infinitely different.
Answer by dalessan9 · Sep 12, 2020 at 05:07 PM
Found the problem. My button was referencing the prefab in folder, not the instance. Visually, it's absolutely identical, but meh.
I used the list to grab the prefab, rather than drag & dropping.
I can relate to update pains but have hard time believing this diagnosis is valid and not some fairly isolated bug. Because given this was true then 2019.4.10f1 wouldn't work for everyone out there (Im using 2020 so dont know) and surely sb would raise the alarm on forums by now (not to mention low chances chances for issue this big slipping through unit-testing regime).
No, I know for a FACT, that this is what's happening - and it's also occurring on the 2019.4.4f1 build - I assumed it wasn't, as I was making a script that I noticed had similar code to an old proj on 2019.4.4f1 - maybe it's a package I added?????
void Awake()
{
Initialized = true;
}
public void CallHoverSfx()
{ // 0
Debug.Log("Uninstantiated Called Hover");
if (Initialized == false) { return; }
Debug.Log("Instance Called Hover.");
}
Console will only show --- "Uninstantiated Called Hover"-- image uploads are taking forever for w/e reason. "Instance Called Hover" debug log is never called.
Are you 100% positive this isn't a race condition? Something like this can happen when CallHoverSfx
is being called before Awake
, for example, from OnEnable
. Also Awake
and all monobehaviour message are being called in order deter$$anonymous$$ed by script execution order settings but also this is slightly mutated by factors that can differ from scene to scene (gameObject instantiation order).
EDIT: Ok, good you solved it :)