Unity & inheritance. Different results DebugMode/Build

Here are my 2 Classes

public class Item : MonoBehaviour
{
[SerializeField] protected TextMeshProUGUI txt_itemNom;
[SerializeField] protected string itemNom;

//No Start
//No Update
}

public class Article : Item
{
public int articleLevel = 1;

public void Start()
{
txt_itemNom.SetText(itemNom);
}

//Called by a button OnClick
{
PlayerRessources.instance.OpenBuyWindow(base.txt_itemNom.text + " Lvl " + articleLevel);
}
}


It is very simple. When I start the game, the GameObject with the Article script set the correct item name in the TextMeshProUGUI object named txt_itemNom. The player can click a button to buy this item, it will displays a confirmation window. And it works perfectly! Or at least, it works when I press Play in the editor but weirldy it behaves differently in the build version.

In the build version, the value of base.txt_itemNom.text in

PlayerRessources.instance.OpenBuyWindow(base.txt_itemNom.text + " Lvl " + articleLevel);


is the original value of base.txt_itemNom.text. (which is "Item name" or something). So I don't get it because base.txt_itemNom.text is correctly setted in the Start because it's displayed in the UI.

It looks like the Article loses its parent class (Item) reference when the player click to OpenBuyWindow(). But only for the TextMeshProUGUI contained in the Item class.

• The Article script is attached to a prefab.
• The prefab is not instantiated by a script. I just added it in the Hierarchy
• If I use the string variable itemNom instead of base.txt_itemNom.text, then it will work.
• @DMGregory To me, it's unecessary to post all the code + the hierarchy view + inspector, but if you think you need it, then I'll do it. Feel free to ask – Sharpnel Apr 30 '20 at 0:35
• Just to confirm: you never call OpenBuyWindow through code - only when a button is clicked? – DMGregory Apr 30 '20 at 0:48
• @DMGregory Exact Greg, only when the button is clicked. – Sharpnel Apr 30 '20 at 0:52
• I don't understand how it's even possible that the game behaves differently between EditorMode and the Build version. I just saw the same problem in another prefab: in the Update, the TextMeshProUGUI text value used when I make a "GET" on it, is the old version of the value, the default value. So weird because the SetText() is effective. I'm getting mad – Sharpnel Apr 30 '20 at 1:51
• There's actually a lot that's different between editor preview and built executables - whole classes of bug that can only show up in-build. So, get used to testing builds regularly and troubleshooting this type of issue, because getting mad doesn't really help anything. 😉 – DMGregory Apr 30 '20 at 1:56

It doesn't look like this has anything to do with inheritance.

Rather, it seems to be a quirk with the TextMeshProUGUI component.

Its text getter doesn't seem to be updated in builds - so it keeps a cache of whatever default value it had populated in the inspector at edit time. (This might be a bug to report to Unity - even if this is by design for runtime efficiency, it should at least issue a warning so the behaviour doesn't catch developers by surprise!)

You can work around this by asking for txt_itemNom.GetParsedText(), which works correctly in build.

Just note that if you've recently set the text (ie. in the same frame, that hasn't had a chance to finish rendering yet), you'll need to call txt_itemNom.ForceMeshUpdate() first, to make sure the text parsing has run on the latest value you set.

Or, since you still have the value you set locally, you cam just use your itemNom string variable directly, without trying to extract the text you set out of the text component itself.

• Since I don't use inheritance a lot, and because the problems are related to this class, I thought it was good to be noticed. Now, I totally agree with you, it seems not related to the problem :( An undiscovered bug like this seems impossible to miss! But yeah I could report it. I just tried txt_itemNom.GetParsedText() and it fixes the problem! So thanks a lot – Sharpnel Apr 30 '20 at 2:08