Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Using Text Mesh Pro UGUI on a prefab

Discussion in 'Getting Started' started by jermainetai0307, Jul 9, 2023.

  1. jermainetai0307

    jermainetai0307

    Joined:
    Nov 10, 2022
    Posts:
    25
    I have this targets that are prefabs so they spawn in individually and get destroyed. this is done thru a script that is attached to a prefab.
    Code (CSharp):
    1.  
    2.     int count = RandomSpawner.counter;
    3.     public GameObject spherePrefab;
    4.     public float pointer = pointcounter.points;
    5.  
    6.     private void Start()
    7.     {
    8.     }
    9.     void OnMouseOver()
    10.     {
    11.         if(Input.GetMouseButtonDown(0))
    12.         {
    13.             Destroy(spherePrefab);
    14.             source.PlayOneShot(clip);
    15.             pointer++;
    16.         }
    17.     }
    and then i have another script attached to the player itself like this
    Code (CSharp):
    1. public class pointcounter : MonoBehaviour
    2. {
    3.     public static float points;
    4.     public TextMeshProUGUI displayText;
    5.    
    6.  
    7.     // Start is called before the first frame update
    8.     void Start()
    9.     {
    10.      
    11.     }
    12.  
    13.     // Update is called once per frame
    14.     void Update()
    15.     {
    16.         string textpoint = points.ToString();
    17.         displayText.text = ("Points:" + textpoint);
    18.     }
    19. }
    Now the reason i have to do another seperate script and put it in the player is because for some reason unity doesnt allow me to drag a text mesh pro object into the object in the inspector. theres prob an obvious reason for this i just dont know. but even after my efforts the points is always on 0 and doesnt move? how can i solve this.
     
  2. Reaktion

    Reaktion

    Joined:
    Nov 8, 2019
    Posts:
    44
    Hi,

    You probably can't serialize your text because of the object you used in your scene.
    If you added a 3D Object/Text, the GameObject will have a Component of type TextMeshPro. If you added an UI/Text (TMPro), the GameObject will have a Component of type TextMeshProUGUI.

    Regarding your score problem :
    In your first script, I can see that you're assigning pointer to be the value of your pointcounter.points. But that doesn't mean they will always have the same value, they are not connected to each other. You just assigned the value of the variable to another.
    In your function
    void OnMouseOver()

    When you're incrementing the pointer, you should really be doing that inside your pointcounter class.
    What you can do is call a function like "IncrementPoints()" inside pointcounter, call it from your first class, and inside, increment the points variable of the pointcounter class.

    Also : Use pascal case nouns for class names. (see more here : Naming and Code Style Tips for C# Scripting in Unity)
     
  3. jermainetai0307

    jermainetai0307

    Joined:
    Nov 10, 2022
    Posts:
    25
    Hi, im not sure what u meant by this, but if i am not wrong the TMPro thing i added was a TextMeshProUGUI.

    I have made the following changes
    Code (CSharp):
    1.     public TextMeshProUGUI displayText;
    2.     public float pointer = pointcounter.points;
    3.     public pointcounter x = new pointcounter();
    4.     void OnMouseOver()
    5.     {
    6.         if(Input.GetMouseButtonDown(0))
    7.         {
    8.             Destroy(spherePrefab);
    9.             source.PlayOneShot(clip);
    10.             pointer++;
    11.  
    12.             x.doSomething();
    13.            
    Code (CSharp):
    1.     public static float points = 0;
    2.     public TextMeshProUGUI displayText;
    3.    
    4.  
    5.     // Start is called before the first frame update
    6.     void Start()
    7.     {
    8.      
    9.     }
    10.  
    11.     public  void doSomething ()
    12.     {
    13.         points++;
    14.         string textpoint = points.ToString();
    15.         displayText.text = ("Points:" + textpoint);
    16.     }
    17.  
    18.    
    19.     // Update is called once per frame
    20.     void Update()
    21.     {
    22.  
    23.         string textpoint = points.ToString();
    24.         displayText.text = ("Points:" + textpoint);
    25.     }
    However the problems remain the same, score stays the same, neither can i put the textmeshpro object into the the prefab thing
     
  4. Reaktion

    Reaktion

    Joined:
    Nov 8, 2019
    Posts:
    44
    Hi,

    TMPro created 2 different class for text that are pretty similar. They created a TextMeshProUGUI, which is used inside Unity canvas' to display a Text in 2D, and you can find it by left clicking inside your hierarchy -> UI -> Text - TextMeshPro.
    There is also a TextMeshPro object, which is a 3D Text that can be displayed like a 3D object (spheres, cubes...), and you can find it by left clicing inside your hierarchy -> 3D Object -> Text - TextMeshPro.
    As you can see, they are very similar inside the editor, but if you choose for example the 3D version of the TextMeshPro, you can't serialize it inside a TextMeshProUGUI variable : it's a TextMeshPro.
    If you created a Canvas and added a UI -> Text - TextMeshPro, you should be able to serialize it inside your variable displayText inside the pointcounter class.
    If not, please add more details to your problem so we can better help you. (show us your text GameObject, and how you're trying to serialize it, to see it fail)

    About your code :
    That's a good start, but you mixed having a score named pointer inside your first class, and a score named points inside your second class. I can also see 2 TextMeshProUGUI variables with the same name : you should keep only one, that will handle the score displayed.
    Keep it simple, and you should start debugging - you can find everywhere on the internet how to do debugging in Unity. Easiest way to understand what your code is doing is by putting
    Debug.Log("My message");

    debugs like this anywhere you need in your code.
    Start debugging the value that you want to track (is that the pointer variable? is that the points variable?) and make sure you're using the correct TextMeshPro GameObject.
     
  5. jermainetai0307

    jermainetai0307

    Joined:
    Nov 10, 2022
    Posts:
    25
    Hi, luckily i have found the problem. it was surprisingly simple all i changed was this.
    Code (CSharp):
    1.         if(Input.GetMouseButtonDown(0))
    2.         {
    3.             Destroy(spherePrefab);
    4.             source.PlayOneShot(clip);
    5.             //pointer++;
    6.  
    7.             pointcounter.points++;
    8.          
    9.         }
    i changed it to pointcounter.points++;

    anyways regarding the TMPro question. i understand what you mean, while i have troubles trying to figure out how to upload a video, i shall try to explain it to the best of my abilities.

    so basically in the inspector of my prefab, since i attached the "click" script to the prefab. there is a slot for me to drag the object into. upload_2023-7-11_21-58-14.png
    now normally i would just drag the Text(TMP) object from the hierarchy into this Display Text slot and it would work. However, when i try to do it on this prefab. it just displays a cross and does not allow me to put it in. therefore my solution was to use an object in my hierarchy and reference that instead. upload_2023-7-11_21-59-30.png
    Now im not sure if i mentioned this, and if i did mayb i didnt make it obvious, but could it be that it worked for the object with the "Pointcounter" script, because it already existed in the hierarchy before the game even boots up? because my prefabs are spawned individually by ANOTHER object in the hierarchy. so basically in my scene, before i press play. the prefab/sphere do not exist at all in my hierarchy.
     
  6. Reaktion

    Reaktion

    Joined:
    Nov 8, 2019
    Posts:
    44
    Doing in your first script
    pointcounter.points++


    Is exactly the same as calling a function inside your class pointcounter that does
    points++;


    I suggested you to do that in order to remove the code from your Update function : score text doesn't have to be refreshed every frame, because it doesn't change every frame, only when you increment it.

    Regarding your serializing problem :
    yes, this could've be the problem. In prefab mode, you will be able to serialize Components/GameObject that are inside your prefab (as direct reference), or you can store another prefab Component, by serializing it from your project files.
    If you're spawning an object, and need a reference to an already existing object, you need to either find this object (you could use GameObject.Find() but I don't recommend using this), or you need to send the reference via the spawner.
    (You could for example give a destination point reference to an Enemy via the EnemySpawner, which knows where the enemies should go)