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 Trying to set up spawn limits

Discussion in 'Scripting' started by theBlackDragon432167, Jun 6, 2023.

  1. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15
    I've stared at tutorials, MS definitions for both dictionaries and lists and I believe I want a dictionary to set a limit for each type I wanted spawned in. The game is like STS and I been trying to make a map like it. I have the "rooms" randomly being place, but I want a limit to each type of room for each floor. This is the code so far

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class AnomilyClusterLogic : MonoBehaviour
    6. {
    7.     private int maxSpawnLimit;
    8.     public event EventHandler OnAnomalySelected;
    9.  
    10.     [SerializeField] private GameObject[] anomalies;
    11.  
    12.     private Dictionary<string, int> SpawnLimit = new Dictionary<string, int>
    13.     {
    14.         {"Space Anomalies Battle", 6},
    15.         {"Space Anomalies Depot", 4},
    16.         {"Space Anomalies Quirks", 4},
    17.         {"Space Anomalies Merchant", 3}
    18.     };
    19.  
    20.     private void Awake()
    21.     {  // only need UnityEngine.Random since I am using both namespaces of Unity and System
    22.  
    23.         int rand = UnityEngine.Random.Range(0, anomalies.Length);
    24.         Instantiate(anomalies[rand], transform.position, Quaternion.identity);
    25.         // Perform logic based on the randomly selected element
    26.         if (rand >= 0 && rand < anomalies.Length)
    27.         {
    28.             GameObject spawnedAnomaly = anomalies[rand];
    29.             OnAnomalySelected?.Invoke(this, EventArgs.Empty);
    30.  
    31.             Debug.Log("Anomaly is :" + spawnedAnomaly + OnAnomalySelected + "Anomaly script is called");
    32.             // Do something with the selected anomaly
    33.             // Example: selectedAnomaly.SetActive(true);
    34.         }
    35.         else
    36.         {
    37.             // Handle the case where the random index is out of bounds
    38.             Debug.LogError("Invalid random index!");
    39.         }
    40.     }
    41. }
    So I am at a loss on how to get these limits in place. I have the event system so when an event does get spawned I can have a listener make the proper event type (I.E spawn the next level, or text based even, ect)
    Thank you for any and all help on this
     
  2. Zalosath

    Zalosath

    Joined:
    Sep 13, 2014
    Posts:
    671
    What is the string key used for in the dictionary? Is this the name of the spawnedAnomaly?

    If it is, just do an if to check if the current number of anomalies with that name matches the limit, if it does, don't spawn the anomaly.
     
  3. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15
    Yes the keys are just the name of the anomalies with the respective spawn limits. I tried doing an IF statement but I cant seem to find the right function or keywords. I tried .contains, I tried .count, I tried .TryGetValue and none of them seem to work when I am comparing it to 0 example
    Code (CSharp):
    1. While (SpawnLimit.   < 0)
    2. {
    3.         spawn in the anomalies
    4. }
    or for loop, even tried foreach. but they all give me an error saying that I cant convert dictionary type string int to int, or sometimes it says bool. Very confusing and none of the doc is very helpful. Some dont even have examples.
     
  4. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15
    Like this?
    Code (CSharp):
    1. private void Awake()
    2.     {  // only need UnityEngine.Random since I am using both namespaces of Unity and System
    3.  
    4.         int rand = UnityEngine.Random.Range(0, anomalies.Length);
    5.         // Perform logic based on the randomly selected element
    6.         if (rand >= 0 && rand < anomalies.Length)
    7.         {
    8.             GameObject spawnedAnomaly = anomalies[rand];
    9.             OnAnomalySelected?.Invoke(this, EventArgs.Empty);
    10.  
    11.             if (spawnedAnomaly != null && spawnedAnomaly > SpawnLimit.Count)
    12.             {
    13.                 Instantiate(anomalies[rand], transform.position, Quaternion.identity);
    14.             }
    15.             else return;
    16.  
    17.                 Debug.Log("Anomaly is :" + spawnedAnomaly + OnAnomalySelected + "Anomaly script is called");
    18.             // Do something with the selected anomaly
    19.             // Example: selectedAnomaly.SetActive(true);
    20.         }
    21.         else
    22.         {
    23.             // Handle the case where the random index is out of bounds
    24.             Debug.LogError("Invalid random index!");
    25.         }
    I get an error here "spawnedAnomaly > SpawnLimit.Count)" I'm most likely not using the right function of the dictionary which is my main problem that I've been trying to find an answer for.

    i meant < but the error still exists
     
    Last edited: Jun 6, 2023
  5. Zalosath

    Zalosath

    Joined:
    Sep 13, 2014
    Posts:
    671
    Not like this exactly. SpawnLimit is a dictionary, so the return of Count is just going to be the number of elements in the dictionary, not the maximum number of spawns. Use SpawnLimit["key"] instead, where key is your anomaly name.
    Also, spawnedAnomaly is a GameObject and therefore cannot be compared with an integer, you need some other way of finding out how many of the selected anomaly have been spawned. You can do this multiple ways, keep track of it while you spawn them, or call GameObject.FindGameObjectsWithTag() or other, your choice. I'd opt for the first option though.
     
  6. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15
    I'll give those a shot ty!
     
  7. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15
    Sadly still not working. I tried this monstrosity
    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using UnityEngine;
    5.  
    6. public class AnomilyClusterLogic : MonoBehaviour
    7. {
    8.     private int maxSpawnLimitBattle;
    9.     private int maxSpawnLimitDepot;
    10.     private int maxSpawnLimitQuirks;
    11.     private int maxSpawnLimitMerchant;
    12.  
    13.     public event EventHandler OnAnomalySelected;
    14.  
    15.     [SerializeField] private GameObject[] anomalies;
    16.  
    17.     private Dictionary<string, int> SpawnLimit = new Dictionary<string, int>
    18.     {
    19.         {"Space Anomalies Battle", 6},
    20.         {"Space Anomalies Depot", 4},
    21.         {"Space Anomalies Quirks", 4},
    22.         {"Space Anomalies Merchant", 3}
    23.     };
    24.  
    25.     private void Awake()
    26.     {  // only need UnityEngine.Random since I am using both namespaces of Unity and System
    27.  
    28.         int rand = UnityEngine.Random.Range(0, anomalies.Length);
    29.         // Perform logic based on the randomly selected element
    30.         if (rand >= 0 && rand < anomalies.Length)
    31.         {
    32.             GameObject spawnedAnomaly = anomalies[rand];
    33.             Instantiate(spawnedAnomaly, transform.position, Quaternion.identity);
    34.             OnAnomalySelected?.Invoke(this, EventArgs.Empty);
    35.  
    36.             List<GameObject> SpaceAnomalyNameCount = new List<GameObject>();
    37.  
    38.           for (int i = 0; i < SpaceAnomalyNameCount.Count && SpaceAnomalyNameCount.Contains<GameObject>(spawnedAnomaly); i++)
    39.           {
    40.                 if (SpaceAnomalyNameCount[i].gameObject == spawnedAnomaly)
    41.                 {
    42.                     GameObject gameObject = SpaceAnomalyNameCount[i];
    43.  
    44.                     while (gameObject.name == "Space Anomalies Battle" && maxSpawnLimitBattle < SpawnLimit["Space Anomalies Battle"] &&
    45.                            gameObject.name == "Space Anomalies Depot" && maxSpawnLimitDepot < SpawnLimit["Space Anomalies Depot"] &&
    46.                            gameObject.name == "Space Anomalies Quirks" && maxSpawnLimitQuirks < SpawnLimit["Space Anomalies Quirks"] &&
    47.                            gameObject.name == "Space Anomalies Merchant" && maxSpawnLimitMerchant < SpawnLimit["Space Anomalies Merchant"])
    48.                     {
    49.                         maxSpawnLimitBattle++;
    50.                         maxSpawnLimitDepot++;
    51.                         maxSpawnLimitQuirks++;
    52.                         maxSpawnLimitMerchant++;
    53.  
    54.                         Debug.Log(maxSpawnLimitBattle + maxSpawnLimitDepot + maxSpawnLimitMerchant + maxSpawnLimitQuirks);
    55.                     }
    56.                 }
    57.                 else Debug.Log("something messed up");
    58.           }
    59.  
    60.  
    61.  
    62.  
    63.                 //Debug.Log("Anomaly is :" + spawnedAnomaly + OnAnomalySelected + "Anomaly script is called");
    64.         }
    65.         else
    66.         {
    67.             Debug.LogError("Invalid random index!");
    68.         }
    69.     }
    70. }

    still not working and my debugs arent showing up either
     
  8. Zalosath

    Zalosath

    Joined:
    Sep 13, 2014
    Posts:
    671
    This does not do anything, you create an empty list and then check if it contains your spawnedAnomaly, which it never will since it's empty.

    Try something like this instead, I don't know exactly what you want though so it might not be entirely fit for purpose.

    Try this, untested, potentially not working code:
    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using UnityEngine;
    5.  
    6. public class AnomilyClusterLogic : MonoBehaviour
    7. {
    8.  
    9.     public event EventHandler OnAnomalySelected;
    10.  
    11.     [SerializeField] private GameObject[] anomalies;
    12.  
    13.     private Dictionary<string, int> SpawnLimit = new Dictionary<string, int>
    14.     {
    15.         {"Space Anomalies Battle", 6},
    16.         {"Space Anomalies Depot", 4},
    17.         {"Space Anomalies Quirks", 4},
    18.         {"Space Anomalies Merchant", 3}
    19.     };
    20.  
    21.     private Dictionary<string, int> SpawnAmount = new Dictionary<string, int>
    22.     {
    23.         {"Space Anomalies Battle", 0},
    24.         {"Space Anomalies Depot", 0},
    25.         {"Space Anomalies Quirks", 0},
    26.         {"Space Anomalies Merchant", 0}
    27.     }
    28.  
    29.     private void Awake()
    30.     {  // only need UnityEngine.Random since I am using both namespaces of Unity and System
    31.  
    32.         foreach (GameObject anomaly in anomalies)
    33.         {
    34.             if (SpawnLimit.ContainsKey(anomaly.name) && SpawnAmount[anomaly.name] < SpawnLimit[anomaly.name])
    35.             {
    36.                 Instantiate(anomaly, transform.position, Quaternion.identity);
    37.                 SpawnAmount[anomaly.name] += 1;
    38.             }
    39.         }
    40.     }
    41. }
     
  9. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    I honestly can't tell what you're trying to achieve, but this sounds like you need a crash course on how dictionaries work.

    Dictionaries are collections of key/value pairs. In your particular example, the element type is
    KeyValuePair<string, int>
    . These are struct value types, and contain
    Key
    and
    Value
    fields, which are of types
    string
    and
    int
    , in that respective order (again, in your particular example).

    Normally you can access the elements of a dictionary by using an indexer.
    Code (csharp):
    1. dict["somekey"] = 5;
    2. Debug.Log(dict["somekey"]);
    But more typically, you access it by TryGetValue, which provides a safe way to both check whether a key exist and pop out its associated value.
    Code (csharp):
    1. if(dict.TryGetValue("somekey", out var value)) {
    2.   Debug.Log($"value found: {value}");
    3. } else {
    4.   Debug.Log("no value was found");
    5. }
    If you don't care about the value, the usual way of checking whether a key is stored is ContainsKey
    Code (csharp):
    1. if(dict.ContainsKey("somekey")) dict.Remove("somekey");
    While trying to refer to an unknown key via indexer will produce an error, setting data via indexer will not, even if that key already existed. You can avoid this behavior by explicitly using
    Add
    . Add will instead produce an error on key duplication.

    Finally, the only way to iterate through this collection is by using foreach, because it implements
    IEnumerable<KeyValuePair<K, V>>
    and
    IDictionary<K, V>
    .
    Code (csharp):
    1. foreach(var kvpair in dict) {
    2.   Debug.Log($"{kvpair.Key}: {kvpair.Value}");
    3. }
    I don't know what IDE you're using, but you should be able to see the exact type of kvpair if you hover over it with your mouse.

    If you're using custom key types with a dictionary, it is worth noting that you ought to implement IEquatable generic interface, as this will mandate Equals and GetHashCode implementations which are crucial to how dictionaries perform and behave (in case you're interested, make sure you learn more about hashing and hash collisions).

    These collections are super-fast by design, and by wisely and strategically deploying them in places of frequent resolution by identity, or in situations where escalation of data would make non-linear algorithmic growth, they can do wonders.

    However, they do not allow the elements to be ordered, and likewise, sorted. Also you can't really random-access the elements, and the collections can't contain duplicate keys.

    Another noteworthy collection in this lineage is HashSet, which is almost identical, except it doesn't have a payload (the value).
     
    Last edited: Jun 6, 2023
  10. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15

    What I'm attempting to do is recreate the map in Slay the Spire, but as my own version for my needs, so I need random rooms, but also need a limit for each room so there isnt like 10 merchant rooms. So I thought a dictionary would be better than a list for the limit amounts when I was looking at tutorials on what dictionaries/lists are and how they work, since they are more flexible than arrays (from what I've seen in tuts and from reading) but I learn from examples, and Unity doesnt have the best examples at least for how I learn and understand.
     
  11. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15
    I use Visual Studios Community Edition
     
  12. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Ok I presume you wanted to make something like a reverse ledger?
    Let's say you have 3 types of rooms, and there can be 2, 4, and 7 of each.

    Your keys can be whatever so you can as well make something more versatile than strings.
    Code (csharp):
    1. public enum RoomType {
    2.   Merchant,
    3.   Ambush,
    4.   Loot
    5. }
    You also need this, it is extractable from the enum, but let's keep it simple
    Code (csharp):
    1. private const int ROOM_TYPES = 3;
    Declare a dictionary like so
    Code (csharp):
    1. Dictionary<RoomType, int> _dict;
    Then you make your dictionary in Start, Awake, or constructor
    Code (csharp):
    1. _dict = new Dictionary<RoomType, int>();
    2. _dict.Add(RoomType.Merchant, 2);
    3. _dict.Add(RoomType.Ambush, 4);
    4. _dict.Add(RoomType.Loot, 7);
    Ideally, you read this from some list in a ScriptableObject or something like that, and build your dictionary automatically.

    Now you can add your rooms. Imagine a dictionary like a bag of items. But you can never just "grab" a random item, you need to address it perfectly. So how do you work around this? Well, you already have an enum, grab a random item from there.
    Code (csharp):
    1. public void BuildRoomList(List<RoomType> listOfRooms, Dictionary<RoomType, int> dict) {
    2.   listOfRooms.Clear(); // prepare the list
    3.  
    4.   while(dict.Count > 0) { // do this while there are items in the dictionary
    5.     int index = Random.Range(0, ROOM_TYPES);
    6.     var roomType = (RoomType)index; // Merchant is internally 0. Ambush is 1 and so on
    7.  
    8.     if(dict.TryGetValue(roomType, out var remaining)) {
    9.       // if we're in here, that means there are items of this type
    10.       listOfRooms.Add(roomType); // so add this type to list
    11.  
    12.       if(remaining > 1) { // if there are still items, just reduce the counter
    13.         dict[roomType] = remaining - 1;
    14.       } else { // if this was the last item, remove this room type completely
    15.         dict.Remove(roomType);
    16.       }
    17.  
    18.     }
    19.   }
    20.  
    21. }
    If you look closely, there is one issue with this approach: initially, any random index will find a valid target, and rooms will get added to the list, but as soon as the dictionary is sufficiently depleted, many attempts to grab something out of it will fail, because the random pick would i.e. try to look for a Merchant room for the hundredth time, yet these are already spent, and so on. So time is needlessly wasted.

    So let's think of a better way to randomly grab something from a dictionary. Here's what you can do: you can walk over the existing room types one by one, for a random amount of steps. This will never fail. Additionally, once you know there is just one room type, you can skip this process altogether.
    Code (csharp):
    1. public void BuildRoomList(List<RoomType> listOfRooms, Dictionary<RoomType, int> dict) {
    2.   listOfRooms.Clear();
    3.   var roomType = (RoomType)0;
    4.  
    5.   while(dict.Count > 0) {
    6.  
    7.     int index = 0;
    8.     int walk = Random.Range(0, ROOM_TYPES) % dict.Count;
    9.     int remaining = 0;
    10.  
    11.     foreach(var kv in dict) {
    12.       roomType = kv.Key;
    13.       remaining = kv.Value;
    14.       if(index++ == walk) break;
    15.     }
    16.  
    17.     // we're absolutely sure this room type exists,
    18.     // because we've just visited it above
    19.  
    20.     listOfRooms.Add(roomType);
    21.  
    22.     if(remaining > 1) {
    23.       dict[roomType] = remaining - 1;
    24.     } else {
    25.       dict.Remove(roomType);
    26.     }
    27.  
    28.   }
    29.  
    30. }
    Now you can do
    Code (csharp):
    1. var myListOfRooms = new List<RoomType>();
    2. BuildRoomList(myListOfRooms, roomTypesDictionary);
    This is just one of the possible implementations. You could also build a list where you govern the amount of room types precisely, but you do it all sequentially. And then you scramble this list. As an example.

    Edit: fixed the const
    Edit2: fixed increment to post on if(index++ == walk) break;
     
    Last edited: Jun 7, 2023
  13. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15

    ty I will look over this and give it a try. I have questions though sorry am new an learning all this. like what does the modular do in "int walk = Random.Range(0, ROOM_TYPES) % dict.Count;" I understand we are getting a random room out of the 3. I'm guessing it's if we have more than 3?

    also the last bit of code is that in a new script or is that the code we use to actually instantiate the procedural rooms.

    Also would I still need my template for the layout of the map and the original GameObject[] array to have the prefabs for the room types?

    thank you again
     
  14. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15
    it's funny that I'm getting a compiler error for the const ROOM_TYPES
     
  15. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15
    Never mind fixed it. Was missing the variable declaration. so I added int to the const
     
  16. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Sure, it's nothing special, there are other ways you could write this.

    Say you've got 7 room types, imagine the following scenarios:

    1) It's early on, and your dictionary has all of the types.
    Well you want to pick any of the 7, so you pick a number between 0 .. 6

    0 % 7 = 0
    1 % 7 = 1
    2 % 7 = 2
    3 % 7 = 3
    4 % 7 = 4
    5 % 7 = 5
    6 % 7 = 6

    So here modulo has no effect.

    2) Some of them got depleted, and now your dictionary has 3 of them.
    You still want to pick any of the 7, so you pick a number between 0 .. 6 to maintain uniformity.
    It's probably nitpicking but then you don't really want to overshoot the items in the dictionary.

    0 % 3 = 0
    1 % 3 = 1
    2 % 3 = 2
    3 % 3 = 0
    4 % 3 = 1
    5 % 3 = 2
    6 % 3 = 0

    So here modulo acts as an upper bound clamp.
    Edit: sorry, in fact, it's slightly better than that, it's actually revolving, so it goes back to 0 and starts counting over

    So after learning this, you can see that I could've written this as
    Code (csharp):
    1. Mathf.Max(Random.Range(0, ROOM_TYPES), dict.Count - 1);
    or
    Code (csharp):
    1. Random.Range(0, dict.Count);
    I just didn't want to change it too much from what we already had in the previous example.
    Edit: and revolving, unlike clamping, improves the randomization.

    This example only builds a randomly populated list out of a dictionary. You would have to build a different machinery to build anything else out of it, but that List.Add I call there is the place where it is safe to hook up anything else you'd prefer instead of just adding some data to a list. You can call InstantiateRoom, or whathaveyou, but I can't possibly write the whole game just to show this.

    Probably. You'd still want the other pieces to interact as you want them.

    Np!

    Of course! Glad you fixed it. Yes it's int. I'm doing this on the fly, pardon my stupid typos.
     
    Last edited: Jun 7, 2023
  17. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    This line is also not very good
    Code (csharp):
    1. if(++index == walk) break;
    should be
    Code (csharp):
    1. if(index++ == walk) break;
    Because if walk is 0 you want that initial 0 to break immediately, but ++index would skip over that.
    Sorry about that. I've done too much code today.
     
  18. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15

    oh yeah of course I dont expect you or anyone to write the whole thing. Just was stuck and needed some guidance. Which tbh we need more of in the examples. the whole myint, myclass. foo/bar doesnt really explain anything meaningful.

    Also just to make sure I understand and am learning the
    Code (CSharp):
    1. public void BuildRoomList(List<RoomType> listOfRooms, Dictionary<RoomType, int> dict)
    is the function or method that actually makes the list. Then I can use whatever else to extract the info from it?

    Again thank you for your help. Now if art was only like this lol
     
  19. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    You can make the list outside of it, then pass it through that method along with the dictionary, and it will populate the list for you. So at the same place you called the method, you now have a populated list, and can pass that elsewhere to do something else. Because the list is now complete, you can just iterate through it blindly and build your rooms. And it is guaranteed that you will have as many rooms as specified by the dictionary, and in some random order.
    Code (csharp):
    1. var dict = new Dictionary<RoomType, int>();
    2. // dict.Add( ... ) // populate the dictionary with entries
    3.  
    4. var list = new List<RoomType>();
    5. BuildRoomList(list, dict); // even if you pass in a full list, it will be wiped by the function with Clear
    6.  
    7. // now you can pass this list to somewhere where you do something with the data
    8. for(int i = 0; i < list.Count; i++) {
    9.   // BuildRoom(i, list[i]);
    10.   Debug.Log(list[i]);
    11. }
    Code (csharp):
    1. // this could be the actual map builder
    2. public void BuildRoom(int index, RoomType roomType) {
    3.  // do some work, produce prefabs, set coordinates etc.
    4. }
     
  20. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15


    This is the last thing I am stuck on I have tried this
    Code (CSharp):
    1.  // now you can pass this list to somewhere where you do something with the data
    2.         for (int i = 0; i < list.Count; i++)
    3.         {
    4.             list = BuildRoom<(i, list[i])>;
    5.             Debug.Log(list[i]);
    6.         }
    Just having issues saving the list. Thank you once again!!
     
  21. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Umm, you sure this isn't waaay over your head?
    I mean I wouldn't want to you to get hurt on those spiky brackets lol

    Nah, you need to learn what you're doing. Learn basics of C# and programming.
    Can't skip that and try to make things.
     
  22. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15
    Code (CSharp):
    1.  public enum roomTemplates
    2.     {
    3.         roomTemplate01,
    4.         roomTemplate02,
    5.         roomTemplate03,
    6.         roomTemplate04,
    7.         roomTemplate05,
    8.         roomTemplate06
    9.     }
    10.  
    11.     public void GetRoomList(List<RoomDictionaries.roomTemplates> listOfRoomTemplates)
    12.     {
    13.         var roomTemplate01 = new Dictionary<RoomDictionaries.RoomType, int>();
    14.         roomTemplate01.Add(RoomType.Anomaly, 5);
    15.         roomTemplate01.Add(RoomType.MajorLoot, 4);
    16.         roomTemplate01.Add(RoomType.Sabatage, 6);
    17.         roomTemplate01.Add(RoomType.Merchant, 3);
    18.         roomTemplate01.Add(RoomType.MinorLoot, 7);
    19.         roomTemplate01.Add(RoomType.Ambush, 8);
    20.  
    21.         var roomTemplate02 = new Dictionary<RoomDictionaries.RoomType, int>();
    22.         roomTemplate02.Add(RoomType.Anomaly, 0);
    23.         roomTemplate02.Add(RoomType.Sabatage, 0);
    24.         roomTemplate02.Add(RoomType.Merchant, 0);
    25.         roomTemplate02.Add(RoomType.MajorLoot, 0);
    26.         roomTemplate02.Add(RoomType.MinorLoot, 0);
    27.         roomTemplate02.Add(RoomType.Ambush, 0);
    28.  
    29.         var roomTemplate03 = new Dictionary<RoomDictionaries.RoomType, int>();
    30.         roomTemplate03.Add(RoomType.Anomaly, 0);
    31.         roomTemplate03.Add(RoomType.Sabatage, 0);
    32.         roomTemplate03.Add(RoomType.Merchant, 0);
    33.         roomTemplate03.Add(RoomType.Ambush, 0);
    34.         roomTemplate03.Add(RoomType.MajorLoot, 0);
    35.         roomTemplate03.Add(RoomType.MinorLoot, 0);
    36.     }
    obviously I havent set all the numbers, but if I understand what you did then this should be the beginnings of creating a List of templates that I can use.
     
  23. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Hey, I was really tired last night, couldn't really go over this in a way that I felt would be helpful.
    Code (csharp):
    1. list = BuildRoom<(i, list[i])>;
    This. is. confusing.
    All function calls in all C-like languages look like funcname(arguments)
    Why stick
    <
    >
    in there?
    Also why use BuildRoom like this when there is an example above that declares it fully
    Code (csharp):
    1. BuildRoom(i, list[i]);
    2.  
    3. public void BuildRoom(int index, RoomType roomType) { ... }
    The point of BuildRoom method is so that you can take the already built list, go through it, and create other content for your game in that order. Having things in some order is the main point of lists. Unlike with dictionaries.

    This doesn't make any sense. You really need to get your bearings right if you want to learn.
    Go back and see how I am using an enum. The reason why I did this is because it's lousy to use numbers or strings in your code just to identify some arbitrary room types.

    Numbers and strings don't look good: in case of numbers, suddenly you have these numbers all over the place, and they don't mean anything. In case of strings, you can read them, so this is better, but your code gets bloated, and what happens if you mistype a string? The compiler won't warn you, and you now get a horrible error, which you have to find by looking each and every string in your code. Not a fun thing to do. Never use strings to drive behavior, if you can help it, use them only for the output, because a typo won't break anything.

    An enum simply let's you have words instead of numbers, in a compiler-friendly manner. You cannot mistype, they do not exert stress on your code and on your eyes, and they behave like numbers in the end. And they are also customizable to an extent.

    That said, enum was specifically used for your room types, not some numbered "template" variables.

    When you need 6 templates, you build an array. But I'm guessing there's already too much stuff going on.

    For starters, learn what enum is. The documentation on C# is pretty massive and easy to search, and these are all pretty simply constructs, at least if you're already handling the basics of Unity scripting, it's not nuclear physics.

    This also can't work. I think it's more beneficial for you if stick to the example as it was, make sure it works on a small scale before attempting to juggle 6 templates and whatnot.
     
  24. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15
    Yeah I was trying to build upon what you did and thought it would make sense to have all the room templates that were made in dictionaries stored in a list so I could easily grab which ever was needed (like If I was using a seed as an example) That's all I was trying to do with the last one was build upon what you did, so I had a lot of templates that could be used and I was storing them in a Scriptable object and then I was trying to adapt your code so I can grab an already made template instead of needing to have one, or having 100 different function calls for it. Sorry if I dont learn like other people. I learn visually and hands on. I understand basics, but its the intermediate stuff that I have issues with like this. Also Unity scripting is different from C# and I have a hard time remembering.
     
  25. theBlackDragon432167

    theBlackDragon432167

    Joined:
    May 26, 2023
    Posts:
    15
    The code snipits from MS site dont explain anything meaningful to someone new at programming. I can do basics all day and 100 different "Hello World" tuts, but they do not dive into all the other functions, methods, properties, variables. They do not go over anything other than .add .remove/sort, when it comes to lists. Also I thought were using Lists and Dictionaries because they are more flex able than Arrays? That's my thinking on why I was putting the templates into a list from the dictionaries. I understand some that Arrays are faster than the 2, but you cannot change an Array at least from all the tuts I've seen and what the doc says.
     
  26. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    There is no tutorial to teach you how to make your own game, right?

    Similarly there is no tutorial to teach you how to program universally. Asking for one when you have superb references with exhaustive examples at your disposal sounds more like an excuse than anything.

    If you're new to programming, keep up with:
    1) high concepts of programming
    2) language features
    3) specific designs, use-cases, and patterns
    4) practice, a lot of it

    Pay attention to how each of the first three categories offers ample examples, but because it assumes that you're a responsible adult with a fully developed cognitive repertoire, tutorialising is deemed unnecessary. And still there are plenty of sites that offer this kind of learning experience, providing excellent coverage of every. single. aspect. of programming.

    In fact, over-tutorialization of Unity is a specific brand by-product of Unity's market penetration, commercial success, and perceived value among its target demographics, giving 3rd-party a sufficient attention-grabbing potential but also reaching out to the ecosystem and teaching it how to use the tool for the mutual benefit.

    C# simply doesn't need such a strategy: they don't need you to like them, or to teach you how to be effective at it. If you don't or can't learn it, you won't land a programming job. There are no C# "indies". Maybe freelancers and outsourcers, but that's a different vibe altogether, and doesn't weigh much on its own. Which is something to ponder about, if nothing else.

    tl;dr You have live access to people with more than 20 years of compressed programming experience, but instead of asking straight questions, you'll rather waste the opportunity and talk about the lack of tutorials.

    Even though, in the end, there is no tutorial to teach you how to make your own game...

    This whole thread is about something that is incredibly easy, compared to producing a unique game from start to finish. I'm not saying this just to sound condescending, but nearly every compact solution in isolation pales in comparison to how complex full game development can get. Just think about how you struggle with connecting a ready-made solution to some other part of your game, then multiply this effort by a factor of thousand. If nothing else, Unity is doing an excellent job of attracting young people only to show them how hard it is, and what's the true value of games as products of manual and intellectual labor.

    No one is going to make your game but you, and to get there you need to learn how to learn on your own.