Editable Letter pop up system + Random Events

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.
!(http://

)

  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.
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class LetterManager : MonoBehaviour
{
    public GameObject letterPanel;
    public GameObject letterPrefab;
    public GameObject letterHolder;

    public List<Letter> letters;
    public List<Letter> receivedLetters;

    [SerializeField] float chanceOfReceive = 0.18f;
    [SerializeField] float chanceOfReceive2 = 0.03f;

    private GameObject currentLetterInstance;

    public void Start()
    {
        letterPanel.SetActive(false);
    }

    public void isLetterComing()
    {
        if (UnityEngine.Random.value < chanceOfReceive)
        {
            SetRandomLetter();

            if(UnityEngine.Random.value < chanceOfReceive2)
            {
                SetRandomLetter();
            }
        }
        else { Debug.Log(" Mektup Yok! "); }

    }


    public void SetRandomLetter()
    {
        Letter chosenLetter = letters[UnityEngine.Random.Range(0, letters.Count)];                // da
        receivedLetters.Add(chosenLetter);

    }

    public void ShowReceivedLetters()
    {
        if (receivedLetters.Count > 0)
        { 
            letterPanel.SetActive(true);

            foreach (Letter letterPopup in receivedLetters)
            {
                GameObject newLetter = Instantiate(letterPrefab, letterHolder.transform);
                Text letterTextTexture = newLetter.transform.Find("letterTextTexture").GetComponent<Text>();
                Image letterTexture = newLetter.transform.Find("letterTexture").GetComponent<Image>();

                Letter letter = newLetter.GetComponent<Letter>();

                letterTextTexture.text = letterPopup.letterText;
                letterTexture.sprite = letterPopup.letterImage;
                newLetter.SetActive(true);

                currentLetterInstance = newLetter;

                Button letterExitButton = newLetter.transform.Find("letterExitButton").GetComponent<Button>();
                // letterExitButton.onClick.AddListener(() => DestroyThisLetter());

                Debug.Log(letterPopup);
            }

            receivedLetters.Clear();
        }

        else
        {
            Debug.Log(" Mektup Yok !");
        }
    }

    public void OpenLetterPanel()
    {
        if(letterPanel != null)
        {
            bool isLatterActive = letterPanel.activeSelf;
            letterPanel.SetActive(isLatterActive);
        }
    }

    public void DestroyCurrentLetter()
    {
        if(currentLetterInstance != null)
        {
          
            Destroy(currentLetterInstance);
        }
      

    }

}

Notes:

  • 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:
public class Letter : MonoBehaviour
{
    public Sprite letterImage;
    public string letterText;

    private Image letterTexture;                              //tried to make these for Prefab
    private TextMeshProUGUI letterTextTexture;


    public void DestroyThisLetter()
    {
        Destroy(gameObject);
    }




}

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:

var letter=Instantiate(letterPrefab, letterHolder.transform);//letter holder is presumably a transform inside a canvas

//pass any variable you need to be set on the new gameobject via a method
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 etc.)

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

1 Like

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: Imgur: The magic of the Internet

  • EndDay button when clicked it is deciding that will player receive a letter? with chanceOfReceive value.
  • Exit button when clicked must destroy this letter (but not working not destroying the letter copy)
  • 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)
  • 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: Imgur: The magic of the Internet (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 letter.GetComponent<Letter>().Setup(letterPopup.letterText,letterPopup.letterImage,letterPopup.letterAccept,letterDecline) 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…

9655853--1374176--Ekran görüntüsü 2024-02-21 102443.png

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.

Cheers