- Home /
[Fixed] Unity UI Text Code Reference magically dissapears
Hey People!
We're busy trying to show product information in an UI. For testing purposes we started with trying to just show the title.
So we have a UIController.cs that handles UI. You can find the source code below for reference.
What happens:
A new UI is loaded in the Scene at runtime
A UIController script is placed in the scene
The UIController uses GameObject.FindObjectWithTag to find the correct Text element
The UIController's method
PopulateUI(Product p)
is calledTextfield should be filled (Which doesn't happen).
The Analysis we've done:
The UI Text Component reference is private: Can't be set outside of class
Is the Text Component actually read from the scene? Using
Debug.Log("[Start] TitleLabel is null: " + titleLabel == null);
-- YesIs the Text Component still referenced right before setting the text? Using
Debug.Log("[PopulateUI] TitleLabel is null: " + titleLabel == null);
-- No (This is wierd)So we check if the moment that the Text component is read from the scene is actually triggered before the
PopulateUI
call usingDebug.Log
-- YesIs the Text component correctly linked? Using
[SerializeComponent]
-- Seems to be, but when the reference is set to null in code the link in the editor stays, so this is unreliable output.Maybe there are multiple UIControllers in the scene? Check using
Debug.Log
in the Awake method. -- No, prints only once.
Then how come the Reference to the Text component is gone? There is no way externally to set the variable since it's private and the only time it gets set is at the Start method. I've included the entire script with output below.
I'm hoping that someone is fimiliar with this problem and can help me out.
Output:
Source:
public class UIController : MonoBehaviour {
[SerializeField]
private Text titleLabel;
private string titleTag = "ProductTitleField";
/// <summary>
/// Populates the Environment UI with the product info
/// </summary>
/// <param name="p">The Product which contains the data of everything that needs to be populated</param>
public void PopulateUI(Product p) {
Debug.Log("[PopulateUI] TitleLabel is null: " + titleLabel == null);
FillLabelIfPossible(titleLabel, p.Title);
}
private void Awake() {
Debug.Log("An Instance of UIController Exists");
}
private void Start() {
titleLabel = GetLabelByTag(titleTag);
Debug.Log("[Start] TitleLabel is null: " + titleLabel == null);
}
private Text GetLabelByTag(string tag) {
GameObject go = GameObject.FindGameObjectWithTag(tag);
if (go == null) {
Debug.LogWarning("Could not find a GameObject tagged with " + tag + ".");
return null;
}
Text t = go.GetComponent<Text>();
if (t == null) {
Debug.LogWarning("Could not find a Text Component on the GameObject tagged with " + tag + ".");
return null;
}
return t;
}
private void FillLabelIfPossible(Text label, string text) {
if (label != null) {
label.text = text;
}
}
}
As a first debug, you could set your inspector to Debug mode so that you can see your label reference in the editor.
Second, you could add a simple component to your found object to see if it gets destroys:
public class Test:$$anonymous$$onoBehaviour{
void OnDestroy(){
Debug.Log("Destroy object");
}
}
then:
GameObject go = GameObject.FindGameObjectWithTag(tag);
go.AddComponent<Test>();
Thanks fafase for the idea! I've added the script but nothing pops up. When I delete the gameobject at runtime manually the log does appear. I attachedthe script on the GO of the Text element and the GO of the UIController.
I've made the reference a [SerializableField] so Debug mode shouldn't make a difference, I did it anyway but nothing changed. I still could see the Text element reference as instantiated while the debug said the reference was null.
It says "Fixed", you should add an edit to let others know what was wrong.
Answer by BluePinguin · Jun 08, 2015 at 07:36 AM
I've fixed the issue. The issue occured because of wrongful Event subscription on my part. When a new environment was loaded the ShopManager subscribed on the UIController to be destroyed instead of the newly instantiated. The scene was destroyed but the UIController class was not gathered by the garbage collector because it was still referenced through script.
Oh well, it's fixed now.
Your answer
Follow this Question
Related Questions
C# How To Save PlayerPrefs for Unity GUI 2 Answers
UI button change variables in another script 1 Answer
How to store a prefab in a variable 1 Answer
Distribute terrain in zones 3 Answers
destroty gui object 1 Answer