Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Question Editable Letter pop up system + Random Events

Discussion in 'UGUI & TextMesh Pro' started by kokolomolokkoo, Feb 20, 2024.

  1. kokolomolokkoo


    Dec 23, 2022
    Hi there, i am a newbie. This is my first non gamejam project.
    Also first Thread entry sorry for any mistakes. Thank you all for your attention.

    I am trying to make a mobil simulation game that mostly consisting images, buttons and texts. For this game i need an advanced letter pop up system that basically works like random event system.

    My question is how can i make it better and efficient. Beacause of my lack of knowledge i did coding but i am not sure this is the right way cuz it's not working as intended.

    1) I wanna know what is the perfect way for taking variables from a list and copying them in a prefab(?) maybe i don't even need a prefab. I just need the instantiate letter game object(?) but i don't think it's good idea since it will be on the canvas. Maybe just instantiating an ui element with necessery variables? but i really want to be able to edit on editor for me to see (both image, text) and maybe add different functions on the same buttons.

    Code (CSharp):
    1. using JetBrains.Annotations;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6. using TMPro;
    8. public class LetterManager : MonoBehaviour
    9. {
    10.     public GameObject letterPanel;
    11.     public GameObject letterPrefab;
    12.     public GameObject letterHolder;
    14.     public List<Letter> letters;
    15.     public List<Letter> receivedLetters;
    17.     [SerializeField] float chanceOfReceive = 0.18f;
    18.     [SerializeField] float chanceOfReceive2 = 0.03f;
    20.     private GameObject currentLetterInstance;
    22.     public void Start()
    23.     {
    24.         letterPanel.SetActive(false);
    25.     }
    27.     public void isLetterComing()
    28.     {
    29.         if (UnityEngine.Random.value < chanceOfReceive)
    30.         {
    31.             SetRandomLetter();
    33.             if(UnityEngine.Random.value < chanceOfReceive2)
    34.             {
    35.                 SetRandomLetter();
    36.             }
    37.         }
    38.         else { Debug.Log(" Mektup Yok! "); }
    40.     }
    43.     public void SetRandomLetter()
    44.     {
    45.         Letter chosenLetter = letters[UnityEngine.Random.Range(0, letters.Count)];                // da
    46.         receivedLetters.Add(chosenLetter);
    48.     }
    50.     public void ShowReceivedLetters()
    51.     {
    52.         if (receivedLetters.Count > 0)
    53.         {
    54.             letterPanel.SetActive(true);
    56.             foreach (Letter letterPopup in receivedLetters)
    57.             {
    58.                 GameObject newLetter = Instantiate(letterPrefab, letterHolder.transform);
    59.                 Text letterTextTexture = newLetter.transform.Find("letterTextTexture").GetComponent<Text>();
    60.                 Image letterTexture = newLetter.transform.Find("letterTexture").GetComponent<Image>();
    62.                 Letter letter = newLetter.GetComponent<Letter>();
    64.                 letterTextTexture.text = letterPopup.letterText;
    65.                 letterTexture.sprite = letterPopup.letterImage;
    66.                 newLetter.SetActive(true);
    68.                 currentLetterInstance = newLetter;
    70.                 Button letterExitButton = newLetter.transform.Find("letterExitButton").GetComponent<Button>();
    71.                 // letterExitButton.onClick.AddListener(() => DestroyThisLetter());
    73.                 Debug.Log(letterPopup);
    74.             }
    76.             receivedLetters.Clear();
    77.         }
    79.         else
    80.         {
    81.             Debug.Log(" Mektup Yok !");
    82.         }
    83.     }
    85.     public void OpenLetterPanel()
    86.     {
    87.         if(letterPanel != null)
    88.         {
    89.             bool isLatterActive = letterPanel.activeSelf;
    90.             letterPanel.SetActive(isLatterActive);
    91.         }
    92.     }
    94.     public void DestroyCurrentLetter()
    95.     {
    96.         if(currentLetterInstance != null)
    97.         {
    99.             Destroy(currentLetterInstance);
    100.         }
    103.     }
    105. }

    • ShowReceivedLetters where magic happens i need an assistance specially there
    • ShowReceivedLetters() calling when clicking mailbox in the game.
    • Letters List: i am draging premade(with image and text) letter game objects to the list in inspector (is it really good idea?)
    • I couldn't destroy letterPrefab clone when clicking exit button onClick (destroy(gameobject) but this game object is the letter game object which only have this code:
      Code (CSharp):
      1. public class Letter : MonoBehaviour
      2. {
      3.     public Sprite letterImage;
      4.     public string letterText;
      6.     private Image letterTexture;                              //tried to make these for Prefab
      7.     private TextMeshProUGUI letterTextTexture;
      10.     public void DestroyThisLetter()
      11.     {
      12.         Destroy(gameObject);
      13.     }
      18. }
  2. venediklee


    Jul 24, 2017
    Not exactly sure what you mean by this.

    It doesnt matter if a gameobject is on a canvas or not for you to instantiate it.

    Again, not exactly sure what you mean by this either. Try sharing some screenshots, it helps(PS: we cant see the image you shared above, you can just copy paste)

    I am *guessing* you want to instantiate letters received by the player on a canvas and display their content.

    You can Instantiate a letter prefab. Then use getcomponent and use a method to assign letter's content:
    Code (CSharp):
    1. var letter=Instantiate(letterPrefab, letterHolder.transform);//letter holder is presumably a transform inside a canvas
    3. //pass any variable you need to be set on the new gameobject via a method
    4. letter.GetComponent<Letter>().Setup(letterPopup.letterText,letterPopup.letterImage)//you'll need create a method called Setup inside of the Letter class that assigns the text and image to the components on that gameobject -- like letterTextTexture.text=text
    These 2 probably shouldn't exist, they are just referencing a sprite asset and a string that can be typed in the editor

    These 2 should be public or have [SerializeField] attribute to show them on the editor. Then you can assign the image component and TextMesh UI text component from the editor.(you'll be using these 2 inside of the Setup method like so:
    letterTexture.sprite=spriteParameter;//spriteParameter is the sprite parameter of the Setup method

    Probably missed some things since I cant even tell what the problem is, let me know if you need help.

    Also, you should probably take some game development courses/tutorials. There is a lot of free ones on youtube like this
    kokolomolokkoo likes this.
  3. kokolomolokkoo


    Dec 23, 2022
    Thank you for your help i am gratefull.

    Excuse me for my english describe level and lack of terminology.
    What i mean is with an image:

    1. EndDay button when clicked it is deciding that will player receive a letter? with chanceOfReceive value.
    2. Exit button when clicked must destroy this letter (but not working not destroying the letter copy)
    3. MailBox button when clicked Setting active the LetterPanel and calling the ShowReceivedLetters which ( i want to instantiate a letter copy from receivedLetters List if there is any for the day)
    4. Letters list is basically a list holding my premade sample letters. With random range function i am adding one letter (will need more than one) to receivedLetters list for system to know what letter did we received for the day.
    Yeah this helped a lot. I think i miss understood the prefabs and instantiate new concepts, will work on it.
    Just one follow up question as you can see here: (Hierarchy is a mess for the moment)
    • i have accept and decline button for each letter. I want to set which button call which method. (which i did in a class basically remove money, remove health, add reputation etc.) So player will read a text from the letter and will make a decision that effects player's money, health, wantedLevel etc.
    So i can
    but before all i have to make some sample gameobject with different variables and functions and need to add these (by draging inside the list in inspector) Letters list for system to hold all sample letters. When needed we can copy as you show from that list. Am i correct?

    Thank you.. unityhelp.png Ekran görüntüsü 2024-02-21 102443.png
  4. venediklee


    Jul 24, 2017
    you need to hold a reference to the instantiated letter or find that letter right before destroying it, then use Destroy(instantiatedLetter). Not sure which part of that isnt working for you

    I cannot understand what you are trying to say mate. Are you trying to prevent the same letter being received more than once? Cant you just remove the letter from the letter list after you send it to the player?

    I have to recommend you watch and implement multiple complete game tutorials before you start working on your own games. And please try to proofread your posts. Maybe even chatgpt can help you proofread.