Working with Dictionary in conjunction with GameObject

For my game of the "get out of the room" type, I want to create hints that appear when you click on the button with a question mark. The hint itself is a 3D object (arrow) pointing to the desired element, these 3D objects are already on the scene, they are just disabled (in the likeness of SetActive (false) but through the inspector). To track which game stage the player is at, I use bool flags, variables that change their value in scripts, with which I interact with.

Example: There is a spoon and a bowl of soup and two more arrows, one pointing to the spoon, the other to the bowl of soup. On the spoon there is a script that processes the click, when you click the spoon is made inactive SetActive (false) and the value of the variable bool changes from true to false, when you click on a bowl of soup, the script hanging on the soup accesses the object "spoon" and takes the value of the variable from there, checks what it is equal to and through the if script decides whether you can use the plate soup.

As a result, I need: GameObject (spoon) on which the script hangs with the bool variable to track whether the spoon was taken or not, GameObject of the 3D arrow itself to know what to activate.

I decided to use the Dictionary so that I could run through the for list in the future, rather than writing a million if's. As a result, I faced two problems.

My Dictionary looks like this (written in void start, otherwise it gives an error):

Dictionary<string, GameObject> dict_help = new Dictionary<string, GameObject>{
{"flag_lochka", GameObject.Find("Подсказка 1")},
{"flag_suup", GameObject.Find("Подсказка 2")}}

As a result, when I write:

print(dict_help["flag_lochka"]);

I get: Hint 1 (UnityEngine.GameObject) UnityEngine.MonoBehaviour:print(Object) Which I think is a good sign, but when I do:

dict_help["flag_lochka"].SetActive(true);

Nothing happens, there are no errors, but the object is not included. This is the first problem, why?

The second problem is that I can only interact with the dictionary in start and cannot in other methods, for example, in "public void Helps ()" it says that there is no dictionary with this name. I tried to solve this problem problem via public Dictionary dict_flag = new Dictionary but in this case, it starts swearing at the syntax before this line (at the opening curly brace from start and at all the following syntax going after the if parentheses, etc.)

If you are interested in the mechanics itself, i.e. why I want to use a Dictionary and how it will work, I will create 2 Dictionaries the first with the subject on which the script hangs and the second Dictionary for the subject (arrows with a hint) name the dictionaries will be different, but the keywords are the same, so I refer to two different dictionaries in the loop, I will be able to simultaneously check what value the bool flag has and at the same time understand what hint to include, since the keyword is the same. I will do this through a loop and the hint will climb out to the first value of the bool flag, for example, if all the flags are initially true and after the interaction they become false, the program searches in the loop from left to right for the first flag with the value true and gives a hint for it. this method is good because my game is not completely linear and some actions can be performed in different order. The next problem that I will face will be related to the fact that the name of the flags and the name of the scripts themselves from where the value of the flags will be taken will be different, so I may need two more Dictionaries with the name of the variable and the name of the script itself (the keyword will be the same in all cases)

Author: CrazyElf, 2021-01-08

1 answers

There is no specificity in the work of Dictionary in conjunction with GameObject.

Here you need to remember about the scope of visibility. When you declare a variable inside a method, it will only be visible inside the method. To make something available inside the class, the private fields of the class are used. To make something globally accessible, public class fields (or properties, but this topic is for another question) are used. So in your case you can do this:

    private Dictionary<string, GameObject> dict_help; // объявляем пустой объект типа Dictionary<string, GameObject> с именем dict_help

    private void Start()
    {
        dict_help = new Dictionary<string, GameObject> // выполняем сложную инициализацию dict_help
        {
            {"flag_lochka", GameObject.Find("Подсказка 1")},
            {"flag_suup", GameObject.Find("Подсказка 2")}
        };
        //Дальше где угодно в классе можем спокойно использовать dict_help
    }

    private void Update()
    {
        dict_help["flag_lochka"].SetActive(true); //пример
    }

If dict_help["flag_lochka"].SetActive(true) works without errors, so everything is correct. For an object named Hint 1 the corresponding check mark in the inspector should change. There are situations where this will not result in visual changes, for example, if the object Hint 1 is a child object of the inactive parent.

 1
Author: ssa112112, 2021-01-08 14:39:31