Button text (TMP) disappears during runtime

Hello!

Quite weird and I know that there must be a super easy fix to the issue - or a configuration I’ve missed, but the problem is that the text element, the children of the default button created from the engine itself, is disappearing during runtime. I have zero idea, why that happens. As it does not happens with other text objects…

Above you can (low-key) see all of my settings - and the issue that I’m trying to fix…

Thanks for any input in advance!

Do you have any scripts referencing to this button and if so, can you share code of them?

Hey, thanks for the reply.
I have the prototype code in a more recent state, so please mind the code segments about keeping score etc.

But I guess the start method should be investigated (?)

using UnityEngine;
using TMPro;
using UnityEngine.UI;
using System.Collections;

[System.Serializable]
public class WeightedNumber
{
    public float weight;  // The weight for this number (the number is implied by its position in the array)
}

public class CardDrawer : MonoBehaviour
{
    // Reference to the GameObject that contains the player's TextMeshPro component
    public GameObject playerCardTextObject;

    // Reference to the GameObject that contains the opponent's TextMeshPro component
    public GameObject opponentCardTextObject;

    // Reference to the GameObject that contains the player's score TextMeshPro component
    public GameObject playerScoreTextObject;

    // Reference to the GameObject that contains the opponent's score TextMeshPro component
    public GameObject opponentScoreTextObject;

    // Reference to the button that triggers the card draw
    public Button drawButton;

    // Array of weights defined by the author in the Editor
    public WeightedNumber[] weightedNumbers;

    // Time delay (in seconds) before the opponent draws their card
    public float opponentDrawDelay = 2.0f;

    // Number of rounds to play
    private int totalRounds = 3;
    private int currentRound = 0;

    // Scores
    private int playerScore = 0;
    private int opponentScore = 0;

    // References to the TextMeshPro components inside the specified GameObjects
    private TextMeshPro playerCardText;
    private TextMeshPro opponentCardText;
    private TextMeshPro playerScoreText;
    private TextMeshPro opponentScoreText;

    void Start()
    {
        // Get the TextMeshPro components from the specified GameObjects
        playerCardText = playerCardTextObject?.GetComponent<TextMeshPro>();
        opponentCardText = opponentCardTextObject?.GetComponent<TextMeshPro>();
        playerScoreText = playerScoreTextObject?.GetComponent<TextMeshPro>();
        opponentScoreText = opponentScoreTextObject?.GetComponent<TextMeshPro>();

        // Ensure the drawButton has the DrawCard method as its onClick listener
        if (drawButton != null)
        {
            drawButton.onClick.AddListener(OnPlayerDraw);
        }
        else
        {
            Debug.LogError("DrawButton is not assigned!");
        }

        // Initialize the scores display
        UpdateScoresDisplay();
    }

    // Method triggered when the player draws a card
    void OnPlayerDraw()
    {
        if (playerCardText != null && opponentCardText != null && weightedNumbers.Length > 0)
        {
            // Disable the draw button to prevent further clicks
            drawButton.interactable = false;

            // Player draws a card
            int playerCardValue = GetWeightedRandomCardValue();
            playerCardText.text = playerCardValue.ToString();

            // Start coroutine to handle opponent's draw after a delay
            StartCoroutine(OpponentDrawAfterDelay(playerCardValue));
        }
        else
        {
            Debug.LogError("Cannot draw cards because one or more components are null or the weightedNumbers array is empty!");
        }
    }

    // Coroutine to handle the opponent's draw after a delay
    IEnumerator OpponentDrawAfterDelay(int playerCardValue)
    {
        // Wait for the specified delay
        yield return new WaitForSeconds(opponentDrawDelay);

        // Opponent draws a card
        int opponentCardValue = GetWeightedRandomCardValue();
        opponentCardText.text = opponentCardValue.ToString();

        // Update scores based on the current round
        UpdateScores(playerCardValue, opponentCardValue);

        // Check if all rounds are complete
        currentRound++;
        if (currentRound >= totalRounds)
        {
            // Display final scores and reset
            DisplayFinalScores();
            ResetGame();
        }
        else
        {
            // Re-enable the draw button for the next round
            drawButton.interactable = true;
        }
    }

    // Method to get a weighted random card value
    int GetWeightedRandomCardValue()
    {
        float totalWeight = 0f;

        // Calculate the total weight
        foreach (WeightedNumber wn in weightedNumbers)
        {
            totalWeight += wn.weight;
        }

        // Generate a random number between 0 and totalWeight
        float randomWeight = Random.Range(0f, totalWeight);

        // Determine which number corresponds to the random weight
        for (int i = 0; i < weightedNumbers.Length; i++)
        {
            if (randomWeight < weightedNumbers[i].weight)
            {
                return i + 1;  // Number is implied by its position (1-indexed)
            }
            randomWeight -= weightedNumbers[i].weight;
        }

        // Fallback, though this should not be reached
        return 1;
    }

    // Method to update scores based on the card values
    void UpdateScores(int playerCardValue, int opponentCardValue)
    {
        if (playerCardValue > opponentCardValue)
        {
            playerScore++;
        }
        else if (playerCardValue < opponentCardValue)
        {
            opponentScore++;
        }
        // No action needed if it's a tie

        UpdateScoresDisplay();
    }

    // Method to update the score display
    void UpdateScoresDisplay()
    {
        if (playerScoreText != null && opponentScoreText != null)
        {
            playerScoreText.text = "Player Score: " + playerScore;
            opponentScoreText.text = "Opponent Score: " + opponentScore;
        }
        else
        {
            Debug.LogError("Score text components are not assigned!");
        }
    }

    // Method to display final scores and reset the game
    void DisplayFinalScores()
    {
        if (playerScoreText != null && opponentScoreText != null)
        {
            playerScoreText.text = "Final Player Score: " + playerScore;
            opponentScoreText.text = "Final Opponent Score: " + opponentScore;
        }
    }

    // Method to reset the game for a new set of rounds
    void ResetGame()
    {
        // Reset scores
        playerScore = 0;
        opponentScore = 0;
        currentRound = 0;

        // Update scores display
        UpdateScoresDisplay();

        // Optionally, re-enable the draw button for the new set of rounds
        drawButton.interactable = true;
    }
}

Couldn’t find references to button’s text in your code. Maybe you accidently referenced text component in scene (you can check it by right-clicking component/object > Find References In Scene). Also as I can see your text containing object not deleted in runtime so check what happens to it.

No, you’re right, there are no references regarding its appearance, content or visibility.
image

Also, I cannot even add more elements to the Canvas as they are also becoming hidden in runtime. I’m switching between Render Modes for the canvas:

  • Screen Space - Camera
    ** Button is not rendered on the camera
  • Screen Space - Overlay
    ** Button is present, no text.
  • World Space
    ** Button is not rendered on the camera

But they are giving different results - none of them are fully functional.

This is confusing…
There must be some layering problems but I’m not sure what to check out.

well, the first step is to create a new button and see if it disapears also

if not then start editing from the begin that button, until you reach the point where it disapears again, or if its fixed

happened many times to me. iirc it’s a matter of setting the wrapping correctly on your text.
or, button is simply too small for the text to fit in (and you have text’s wrapping set to Truncate). yeah, and in editor sometimes you get different results

Hey!
This is going to be crazy but… I’ve found the problem.
Even though I started up a 2D project (I never did in 3 years), it never occured to me that the depth of an asset, its position on the Z axis would be the key. These problems were coming from one item was being in front of another. This is super stupid on my side, but never thought that the 3rd dimension could confuse my 2D system…
:confused:

I feel dumb.

dont sweat it, such things is business as usual, happens all the time to anyone