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

Resolved Referencing just the number in a GameObject's name?

Discussion in 'Scripting' started by pocketey_change, Jun 16, 2023.

  1. pocketey_change

    pocketey_change

    Joined:
    Jun 15, 2023
    Posts:
    6
    Hello,

    I'm trying to make five Flower objects instantiate prefab models in order to display the contents of an array. I've written two scripts: one for the parent GameObject holding the Flower object, the Bouquet, and one for the flowers themselves. The flowers are named Flower1, Flower2, etc. So far, these scripts work great on Flower1.

    I want to use the same script in each Flower to make it easier to change later, but each Flower needs to check a different index in the flower inventory array to see what type of flower it needs to be. Is there a way to reference just these numbers in the name? Or would I have to use an ID of sorts? I'm honestly very lost on how to do this.

    I've tried googling answers but my questions are either too specific or they yield irrelevant information. I'm very new to Unity so maybe I just don't know what to search?
    Below are the two scripts that I've made so far.

    The Bouquet's script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class BouquetStorage : MonoBehaviour
    6. {
    7.     public int[] currentFlowerIDs = new int[] { 0, 0, 0, 0, 0 }; //0 is None, 1 is Red, 2 is Blue, 3 is Yellow
    8.     public int currentFlowerCount = 0;
    9.  
    10.     public void addFlower(int flowerTypeIndex)
    11.     {
    12.        
    13.         for (int i = 0; i < currentFlowerIDs.Length; i++)
    14.         {
    15.  
    16.             if (currentFlowerIDs[i] == 0)
    17.             {
    18.                 currentFlowerCount++;
    19.                 currentFlowerIDs[i] = flowerTypeIndex;
    20.  
    21.                 break;
    22.             }
    23.         }
    24.     }
    25.  
    26.     // Start is called before the first frame update
    27.     void Start()
    28.     {
    29.         addFlower(1);
    30.         addFlower(2);
    31.  
    32.     }
    33.  
    34.     // Update is called once per frame
    35.     void Update()
    36.     {
    37.  
    38.     }
    39. }
    Flower1's script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class FlowerChangerScript : MonoBehaviour
    6. {
    7.     public BouquetStorage bouquetStorage;
    8.     public int flowerType = 0;
    9.     public GameObject[] flowerPrefabs = new GameObject[4];
    10.     int lastFlowerType = 0;
    11.    
    12.     // Start is called before the first frame update
    13.     void Start()
    14.     {
    15.        
    16.        
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void Update()
    21.     {
    22.         flowerType = bouquetStorage.currentFlowerIDs[0]; // <- i would like the index to change based on which flower object the script is on
    23.         if (lastFlowerType != flowerType)
    24.         {
    25.             Instantiate(flowerPrefabs[flowerType], new Vector3(0, 0, 0), Quaternion.identity, gameObject.transform);
    26.             lastFlowerType = flowerType;
    27.         }
    28.     }
    29. }
    30.  
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    I think you want an array of Flower[] in your Bouquet.

    The Bouquet probably doesn't care about the type, and if it did, it should access one single
    public int flowerType;
    in a single Flower

    That way you can make as many flower prefabs as you like, just change that public ID on each one.

    Alternately you might consider ScriptableObjects:

    ScriptableObject usage in RPGs:

    https://forum.unity.com/threads/scr...tiple-units-in-your-team.925409/#post-6055289

    https://forum.unity.com/threads/cre...ssigned-in-the-inspector.946240/#post-6174205

    Usage as a shared common data container:

     
  3. pocketey_change

    pocketey_change

    Joined:
    Jun 15, 2023
    Posts:
    6
    The ScriptableObject route seems intriguing.
    Would I create a ScriptableObject for each flower type and then make an instance of it when that flower type is added to the bouquet?
    If that's the case would I also keep the currentFlowerIDs array and use it to decide which objects to have at any given time at runtime?
    I'd also like to be able to give each flower (regardless of type) a different rotation in order to give the bouquet visual variety.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    No, you don't need to make an instance per bouquet... you would have a "Rose type 1" SO, then a "Rose type 2" SO, etc. If you had 57 instances of "Rose Type 1" they would all point to the "Rose Type 1" SO.

    Or you can just make prefabs, either way. It comes down to trying to repeat yourself as little as possible, whichever organization way makes the most sense to you.
     
  5. pocketey_change

    pocketey_change

    Joined:
    Jun 15, 2023
    Posts:
    6
    I don't think multiple rose types is a good idea.

    I re-read my original post and realized that I think I left out some key details: the different flowers have different "mood" and "color" stats that are added together to get the final bouquet stat. This is so that the player will make bouquets that fulfill certain requirements from NPCS.

    For example, an NPC might ask for a "romantic" bouquet, and internally that might mean that the bouquet must have at least 5 romance stat. I'm interested in using ScriptableObjects because they, inherently, hold stat information, so they seem like a perfect fit.

    The problem I'm running into is keeping track of what flowers are in the bouquet the player is currently holding, and telling those flowers what they need to look like at any given frame. The natural solution (to me at least) is to make an array of ScriptableObjects to hold the current flowers in the Bouquet object, and then instantiating copies of the correct prefabs of the flower models to display the bouquet. However, I cannot for the life of me find an effective way online of creating and editing the data in a ScriptableObject array. I've tried googling things like "how to make an array of ScriptableObjects" and "how to reference a ScriptableObject in Unity" but it's full of people who already are doing it in their code and need help bug fixing.

    Basically, I'm trying to make a sort of inventory system, only instead of displaying the items in a menu, they are rendered together to form a bouquet. The rendering part is what makes most inventory tutorials very unhelpful - the tutorials are based around a GUI to access the inventory and I just don't know enough about c# to parse out the useful bits.

    Here is the current script I have for the Flower SO:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [CreateAssetMenu]
    6.  
    7. public class Flowers : ScriptableObject
    8. {
    9.     public string flowerType;
    10.  
    11.     public GameObject prefab;
    12.  
    13. //These ints are for calculating the final bouquet's stats to check if it meets the requirements for the NPC request.
    14.     public int red;
    15.     public int orange;
    16.     public int yellow;
    17.     public int green;
    18.     public int blue;
    19.     public int purple;
    20.  
    21.     public int sunny;
    22.     public int romance;
    23.     public int mourning;
    24.     public int peaceful;
    25. }
    26.  
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    First of all, you are on the right track ScriptableObject-wise.

    Knowing a flower by a single object, in this case the Flower, which tell show to make it, etc., that's the point.

    It gets you out of having a central list in code. Instead the data just drives it. More varieties? Make more Flower instances on disk, drag them in.

    There's really only one fix for this: learn it. :) Try this guy's approach:

    Imphenzia: How Did I Learn To Make Games:



    Tutorials and example code are great, but keep this in mind to maximize your success and minimize your frustration:

    How to do tutorials properly, two (2) simple steps to success:

    Step 1. Follow the tutorial and do every single step of the tutorial 100% precisely the way it is shown. Even the slightest deviation (even a single character!) generally ends in disaster. That's how software engineering works. Every step must be taken, every single letter must be spelled, capitalized, punctuated and spaced (or not spaced) properly, literally NOTHING can be omitted or skipped.

    Fortunately this is the easiest part to get right: Be a robot. Don't make any mistakes.
    BE PERFECT IN EVERYTHING YOU DO HERE!!


    If you get any errors, learn how to read the error code and fix your error. Google is your friend here. Do NOT continue until you fix your error. Your error will probably be somewhere near the parenthesis numbers (line and character position) in the file. It is almost CERTAINLY your typo causing the error, so look again and fix it.

    Step 2. Go back and work through every part of the tutorial again, and this time explain it to your doggie. See how I am doing that in my avatar picture? If you have no dog, explain it to your house plant. If you are unable to explain any part of it, STOP. DO NOT PROCEED. Now go learn how that part works. Read the documentation on the functions involved. Go back to the tutorial and try to figure out WHY they did that. This is the part that takes a LOT of time when you are new. It might take days or weeks to work through a single 5-minute tutorial. Stick with it. You will learn.

    Step 2 is the part everybody seems to miss. Without Step 2 you are simply a code-typing monkey and outside of the specific tutorial you did, you will be completely lost. If you want to learn, you MUST do Step 2.

    Of course, all this presupposes no errors in the tutorial. For certain tutorial makers (like Unity, Brackeys, Imphenzia, Sebastian Lague) this is usually the case. For some other less-well-known content creators, this is less true. Read the comments on the video: did anyone have issues like you did? If there's an error, you will NEVER be the first guy to find it.

    Beyond that, Step 3, 4, 5 and 6 become easy because you already understand!

    And just for full disclosure, keep this in mind:

    These things (inventory, shop systems, character customization, dialog tree systems, crafting, etc) are fairly tricky hairy beasts, definitely deep in advanced coding territory.

    Inventory code never lives "all by itself." All inventory code is EXTREMELY tightly bound to prefabs and/or assets used to display and present and control the inventory. Problems and solutions must consider both code and assets as well as scene / prefab setup and connectivity.

    Inventories / shop systems / character selectors all contain elements of:

    - a database of items that you may possibly possess / equip
    - a database of the items that you actually possess / equip currently
    - perhaps another database of your "storage" area at home base?
    - persistence of this information to storage between game runs
    - presentation of the inventory to the user (may have to scale and grow, overlay parts, clothing, etc)
    - interaction with items in the inventory or on the character or in the home base storage area
    - interaction with the world to get items in and out
    - dependence on asset definition (images, etc.) for presentation

    Just the design choices of such a system can have a lot of complicating confounding issues, such as:

    - can you have multiple items? Is there a limit?
    - if there is an item limit, what is it? Total count? Weight? Size? Something else?
    - are those items shown individually or do they stack?
    - are coins / gems stacked but other stuff isn't stacked?
    - do items have detailed data shown (durability, rarity, damage, etc.)?
    - can users combine items to make new items? How? Limits? Results? Messages of success/failure?
    - can users substantially modify items with other things like spells, gems, sockets, etc.?
    - does a worn-out item (shovel) become something else (like a stick) when the item wears out fully?
    - etc.

    Your best bet is probably to write down exactly what you want feature-wise. It may be useful to get very familiar with an existing game so you have an actual example of each feature in action.

    Once you have decided a baseline design, fully work through two or three different inventory tutorials on Youtube, perhaps even for the game example you have chosen above.

    Breaking down a large problem such as inventory:

    https://forum.unity.com/threads/weapon-inventory-and-how-to-script-weapons.1046236/#post-6769558

    If you want to see most of the steps involved, make a "micro inventory" in your game, something whereby the player can have (or not have) a single item, and display that item in the UI, and let the user select that item and do things with it (take, drop, use, wear, eat, sell, buy, etc.).

    Everything you learn doing that "micro inventory" of one item will apply when you have any larger more complex inventory, and it will give you a feel for what you are dealing with.

    Breaking down large problems in general:

    https://forum.unity.com/threads/opt...n-an-asteroid-belt-game.1395319/#post-8781697
     
  7. dlorre

    dlorre

    Joined:
    Apr 12, 2020
    Posts:
    700
    Just add flowerTypeIndex to your SO and initialize it in addFlower()? Alternatively you could make an array of flower like Kurt said and use IndexOf().