Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

C# arrays not working as expected

Discussion in 'Scripting' started by Gnimmel, Nov 25, 2014.

  1. Gnimmel

    Gnimmel

    Joined:
    Apr 21, 2010
    Posts:
    358
    I have an array of a custom "Loot" class;

    Code (CSharp):
    1.  
    2. public Loot[] Inventory = new Loot[30];
    3.  
    This is defined in a script which I then later access in another script like so;

    Code (CSharp):
    1. GameDataScript = (GameData_Script) GameDataOB.GetComponent(typeof(GameData_Script));
    2.  
    I'm trying to set all the values in the array with a loop and it seems to set all the elements to the same value, the last one in the loop. As you can see I'm pulling the values from playerPrefs just as a temp solution for a save game.

    Code (CSharp):
    1.            
    2. for(Loop = 0; Loop < 30; Loop++)
    3. {
    4.   GameDataScript.Inventory[Loop].LootInfo =  PlayerPrefs.GetString(("LootInfo" + Loop));
    5.   GameDataScript.Inventory[Loop].Value =  PlayerPrefs.GetInt(("Value" + Loop));
    6.   GameDataScript.Inventory[Loop].LootCostValue =  PlayerPrefs.GetInt(("LootCostValue" + Loop));
    7. }
    For now I've got my code working by creating a local version of the array, setting that and then copying it to the one in the GameDataScript, however, I'm interested in why I have to do it that way?
     
  2. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    Are your secondary variables of the array, public?
     
  3. Kirk Clawson

    Kirk Clawson

    Joined:
    Nov 4, 2014
    Posts:
    65
    Is Loot a class or a struct? Your line of code:
    Code (CSharp):
    1. public Loot[] Inventory = new Loot[30];
    Is only new-ing up the array, not the individual Loot instances, and since you don't show where you're new-ing up those, I don't know if it's being properly instanciated. Inside your loop, try this:
    Code (CSharp):
    1. for(Loop = 0; Loop < 30; Loop++)
    2. {
    3.   GameDataScript.Inventory[Loop] = new Loot(); // Might need to use Instantiate() if it's a GameObject
    4.   GameDataScript.Inventory[Loop].LootInfo =  PlayerPrefs.GetString(("LootInfo" + Loop));
    5.   GameDataScript.Inventory[Loop].Value =  PlayerPrefs.GetInt(("Value" + Loop));
    6.   GameDataScript.Inventory[Loop].LootCostValue =  PlayerPrefs.GetInt(("LootCostValue" + Loop));
    7. }
     
  4. Gnimmel

    Gnimmel

    Joined:
    Apr 21, 2010
    Posts:
    358
    Thanks for the reply's, I'll try and elaborate a bit more.

    This is the full Loot class;

    Code (CSharp):
    1. public enum LootTypes { Helmet, ChestArmor, Gloves, Sheild, Boots, Sword, LegArmor, ShoulderArmor, Potion, None};
    2.  
    3. public enum LootSpells {None, AddHealth, AddStamina, DoubleDamage, FireDamage, ColdDamage};
    4.  
    5. [System.Serializable]
    6. public class Loot
    7. {
    8.     public string LootInfo;
    9.     public LootTypes LootType;
    10.     public int Value;              
    11.     public int LootCostValue;          
    12.     public LootSpells LootSpell;
    13.     public int LootPrefabArrayNum;  
    14.     public Texture2D LootIcon;
    15.     public bool Consumable;          
    16.     public int EquipmentGO_Barbarian;          
    17.     public int Level;
    18.     public int ValRand_Low;          
    19.     public int ValRand_High;      
    20.  
    21. }
    22.  
    I have a prefab object with the GameData_Script attached which has the array like this;
    Code (CSharp):
    1. public class GameData_Script : MonoBehaviour
    2. {
    3.   public Loot[] Inventory = new Loot[30];
    4.  
    5. ...
    6. }
    .
    and finally in the code that is having problems, I'm instantiating the game object like so;

    Code (CSharp):
    1. GameDataOB = (GameObject) Instantiate(GameDataPrefab);
    2. GameDataOB.name = ("GameData_Prefab");
    3.  
    4. GameDataScript = (GameData_Script) GameDataOB.GetComponent(typeof(GameData_Script));
    5.  
    And it's a few lines down that I try and set the values, just after setting a few more that are not in the array, but work fine.

    As I said, for now making a local version of the array and loading that up first works fine, so I have everything working, but I'd like to know what I'm missing about classes and arrays.

    Thanks again for taking a look at this.
     
  5. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    Where are you creating the instances for your Loot class?
     
  6. Gnimmel

    Gnimmel

    Joined:
    Apr 21, 2010
    Posts:
    358
    I'm just using the array after declaring it in my game data script (public Loot[] Inventory =new Loot[30];). This has worked fine in all my other scripts, but this is the first time I've tried to load all the values with a loop.

    I've declared the same array in my player script which I use to hold the inventory, this duplicate is used to save my data between scenes etc.

    Is this my problem, have I missed something about creating the array/class?
     
  7. Kirk Clawson

    Kirk Clawson

    Joined:
    Nov 4, 2014
    Posts:
    65
    Since you marked the class as serializable, and some/all of it is exposed to the Unity Editor, there is going to be some instance weirdness going on, which is why it sort-of-works-sort-of-doesn't.

    To pull it out of the Unity world into a pure programming exercise, this code does not work. It will throw a null reference exception the first iteration of the loop:
    Code (CSharp):
    1. SomeClass[] values = new SomeClass[30];
    2. for (int i = 0; i < 30; i++)
    3. {
    4.     values[i].SomeValue = "Something";
    5.     values[i].SomeOtherValue = 42;
    6. }
    You have to initialize the individual array elements as well. This code does work:
    Code (CSharp):
    1. SomeClass[] values = new SomeClass[30];
    2. for (int i = 0; i < 30; i++)
    3. {
    4.     values[i] = new SomeClass();
    5.     values[i].SomeValue = "Something";
    6.     values[i].SomeOtherValue = 42;
    7. }
     
  8. Gnimmel

    Gnimmel

    Joined:
    Apr 21, 2010
    Posts:
    358
    OK, that makes a little more sense to me. It shows I still have much to learn about classes etc.

    Thanks for the reply, I will add this to my code when I get the chance latter today.
     
  9. N1NNIE

    N1NNIE

    Joined:
    Nov 3, 2020
    Posts:
    8
    This grenade code is working fine but on line 24 it gives me an error:
    error CS0029: Cannot implicitly convert type 'UnityEngine.Collider[]' to 'Collider[]'
    and i dont know why because i did everything like the video did so can someone plz help me. Here is the script:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class Grenade : MonoBehaviour {

    public float delay = 3f;
    public float radius = 5f;
    public float force = 700f;
    public float power = 10.0F;

    float countdown;

    public GameObject explosionEffect;

    bool hasExploded = false;

    // Use this for initialization
    void Start ()
    {
    countdown = delay;

    Vector3 explosionPos = transform.position;
    Collider[] colliders = Physics.OverlapSphere(explosionPos, radius);
    foreach (Collider hit in colliders)
    {
    Rigidbody rb = hit.GetComponent<Rigidbody>();

    if (rb != null)
    rb.AddExplosionForce(power, explosionPos, radius, 3.0F);
    }
    }

    void Update ()
    {
    countdown -=Time.deltaTime;
    if (countdown <= 0f &&! hasExploded)
    {
    Explode();
    hasExploded = true;
    }
    }

    void Explode()
    {
    Instantiate(explosionEffect, transform.position, transform.rotation);

    Destroy(gameObject);
    }
    }
     
  10. N1NNIE

    N1NNIE

    Joined:
    Nov 3, 2020
    Posts:
    8
    note: its just one error
     
  11. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Please don't reply to SEVEN YEAR OLD threads with new and completely unrelated issues.

    First of all, it's against forum rules.

    Second of all, make your own fresh post... it's FREE!

    When you post, keep these things in mind:

    How to report your problem productively in the Unity3D forums:

    http://plbm.com/?p=220

    How to understand compiler and other errors and even fix them yourself:

    https://forum.unity.com/threads/ass...3-syntax-error-expected.1039702/#post-6730855

    If you post a code snippet, ALWAYS USE CODE TAGS:

    How to use code tags: https://forum.unity.com/threads/using-code-tags-properly.143875/