Search Unity

Code works, but not populating string array in inspector

Discussion in 'Editor & General Support' started by jleven22, Jan 25, 2021.

  1. jleven22

    jleven22

    Joined:
    Mar 26, 2019
    Posts:
    421
    For some reason my code is working fine, but I'm not seeing the changes reflected in the inspector window.

    Here is a SCREENSHOT OF THE INSPECTOR.

    Here is the code:

    Code (CSharp):
    1.     public void AddItem(string itemToAdd)
    2.     {
    3.  
    4.         Debug.Log("itemToAdd = " + itemToAdd);
    5.  
    6.  
    7.         int newItemPosition = 0;
    8.         bool foundSpace = false;
    9.  
    10.         for (int i = 0; i < itemsHeld.Length; i++)
    11.         {
    12.             if(itemsHeld[i] == "" || itemsHeld[i] == itemToAdd)
    13.             {
    14.                 newItemPosition = i;
    15.                 i = itemsHeld.Length;
    16.                 foundSpace = true;
    17.  
    18.                 Debug.Log("newItemPosition = " + newItemPosition);
    19.  
    20.             }
    21.         }
    22.  
    23.         if (foundSpace)
    24.         {
    25.             bool itemExists = false;
    26.  
    27.             for (int i = 0; i < referenceItems.Length; i++)
    28.             {
    29.                 if(referenceItems[i].itemName == itemToAdd)
    30.                 {
    31.                     itemExists = true;
    32.                     i = referenceItems.Length;
    33.                 }
    34.             }
    35.  
    36.             if (itemExists)
    37.             {
    38.                 itemsHeld[newItemPosition] = itemToAdd;
    39.                 numberOfItems[newItemPosition]++;
    40.             }
    41.             else
    42.             {
    43.                 Debug.LogError(itemToAdd + " does not exist!");
    44.             }
    45.         }
    46.  
    47.         UIController.instance.ShowItems();
    48.  
    49.     }
    50.  
    Everything here is working just fine. The game is acting like I have picked up the item. It is, in theory, adding the item to itemsHeld using the correct numberOfItems.

    BUT the inspector is showing every slot in both arrays as empty (screenshot only shows itemsHeld as empty, but all numberOfItems slots are set to 0).

    Never encountered this before so quite lost. Any help appreciated!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,739
    You have Debug.Log() statements in there already, KEEP GOING! You're only one Debug.Log() statement away from knowing what string your code is injecting into each element in the array... don't stop now!
     
    Joe-Censored and jleven22 like this.
  3. jleven22

    jleven22

    Joined:
    Mar 26, 2019
    Posts:
    421
    I believe I updated to your liking here:
    Code (CSharp):
    1.             if (itemExists)
    2.             {
    3.                 itemsHeld[newItemPosition] = itemToAdd;
    4.                 Debug.Log("itemsHeld[newItemPosition] = " + itemsHeld[newItemPosition]);
    5.                 numberOfItems[newItemPosition]++;
    6.             }
    But once again, the code is working just fine. The debug returns the item name as expected. But the inspector isn't populating the array.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,739
    Is the itemsHeld in this function the actual public field in the inspector? Or did it get copied... if it got copied in certain ways, you might only be modifying the copy, not the original.

    Best is always to put known values like "FOO" in there, then in other code far away from here (completely different script), try and read it back and see if it is still "FOO" or not.

    If it got copied, you might just need to assign it back. Also, maybe the inspector is lagging out. What if you press pause and try to edit one of those fields, then read it back in code.

    Remember it's just data, nothing else... track it down, bloodhound it, find the leak.
     
  5. jleven22

    jleven22

    Joined:
    Mar 26, 2019
    Posts:
    421
    Ok so I'm a little lost on this reply. How would I know if it got copied? As far as I know I've set everything up to populate the itemsHeld[] and that should be that - is there something I'm missing here? Still fairly new to C# so it's likely I just don't understand what you mean.

    Also, not sure what you mean by the FOO. Can you elaborate on that? I tried googling but didn't find anything relevant.
     
  6. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    https://en.wikipedia.org/wiki/Metasyntactic_variable

    Small note not directly related to your problem -- you are using statements like
    i = referenceItems.Length
    to shortcut to the end of the loop. While technically correct, and a clever solution, this is unnecessary. There are already two statements for loop control built into the language:
    break
    and
    continue
    .
    break
    will instantly "break" out of the loop and continue execution, while
    continue
    will instantly skip to the end of the current iteration (and therefore immediately start the next one). In this instance, your statement is a functional replacement for
    break
    .
     
  7. jleven22

    jleven22

    Joined:
    Mar 26, 2019
    Posts:
    421
    Thx this is helpful. Good link.

    Part I am stuck at now is just the fact I don't know where data is being sent. If not being sent to array in inspector, how can I determine where it's living? It's quite confusing.
     
  8. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    I've looked closer at your code. Are you seeing any "<item> does not exist" log entries?

    There are several ways to make your code more concise. First, you are checking whether an item is valid after you check if there is a space for it. If the item is invalid, then checking for a space is unnecessary.

    Additionally, there is no need to keep an array for each portion of your data -- you can consolidate these in a
    struct
    , which acts a bit like a lightweight class with a few of its own rules. I've sketched out what the code might look like if these changes were made. These will also help to make it less error-prone as you have fewer moving parts.

    Code (CSharp):
    1. // I'm converting it to a list for convenient resizing
    2. public List<ItemData> itemsHeld;
    3.  
    4. public struct ItemData {
    5.     public string itemName;
    6.     public int count;
    7. }
    8.  
    9. // separating out the maximum items from the size of the array
    10. // allows you more fine-grained control over the configuration
    11. public int maxItemsHeld = 40;
    12.  
    13. public void AddItem ( string itemToAdd ) {
    14.     if( !Array.Exists( referenceItems, item => item.itemName == itemToAdd ) ) ) {
    15.         Debug.LogError( $"Cannot pick up item: {itemToAdd} does not exist!" );
    16.     }
    17.  
    18.     // check if we're already holding that item
    19.     for( int i = 0; i < itemsHeld.Count; i++ ) {
    20.         if( itemsHeld[ i ].itemName == itemToAdd ) {
    21.             itemsHeld[ i ].count += 1;
    22.             // I would be tempted to separate these calls out from this method
    23.             // as there may be times when you want to add items without
    24.             // showing them.
    25.             UIController.instance.ShowItems();
    26.             return;
    27.         }
    28.     }
    29.  
    30.     // item isn't already being held
    31.     if( itemsHeld.Count < maxItemsHeld ) {
    32.         ItemData data = new ItemData();
    33.  
    34.         data.itemName = itemToAdd;
    35.         data.count = 1;
    36.  
    37.         // the itemsHeld array automatically resizes as needed.
    38.         itemsHeld.Add( data );
    39.     } else {
    40.         Debug.LogError( "Cannot pick up item: you are overencumbered!" );
    41.     }
    42.  
    43.     UIController.instance.ShowItems();
    44. }
     
  9. jleven22

    jleven22

    Joined:
    Mar 26, 2019
    Posts:
    421
    So I did figure it out... it was a lot of work and super complicated. Too complicated to try and explain here. But I did figure it out and your suggestions help. Thx!
     
    Madgvox likes this.
  10. jleven22

    jleven22

    Joined:
    Mar 26, 2019
    Posts:
    421
    Just came back to say thank you so much for your support over the past few weeks. You and your dog have been helping me on several different problems. In the end, you were right - it was up to me to dive deep and figure it out. Turns out, it was a whole mess of bugs. Too complicated of a mess to get into here. But I did figure it out!

    The short of it came down to two things:
    - I was using a Unity Asset called Easy Save 3 to save and load data. The way this was getting loaded into the scene was screwy and required a lot of tinkering to make function properly in my various references across several scripts.
    - I was using "" in some places for the string array, and null in other places. These two did not play well. But it would have been hard to describe over the forum, without posting all 5 of my scripts checking this array.

    So anyway, thank you so much for the support. You are the man and make n00bs's lives like mine much easier!

    If you're on itch.io you can follow the progress when I've got something to update:
    https://ohnoponogames.itch.io/you-are-dead-demo

    You da man
     
    Kurt-Dekker likes this.
  11. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,739
    That's awesome and of course you're welcome! Glad you're cooking again.

    Ha, yes, I've done this in the past. Fortunately there is some help from C#... there's the
    string.IsNullOrEmpty()
    method:

    Code (csharp):
    1. if (string.IsNullOrEmpty( myString))
    2. {
    3.   // we have data!
    4. }
    5. else
    6. {
    7.   // we got nuthin
    8. }