error with list & struct
Hi im getting a weird error when using a list and struct and trying to call a specific element from a list.
public List<Transform> selectedUnits = new List<Transform>();
public List<unit> units = new List<unit>();
[System.Serializable]
public struct unit
{
public Transform trans;
public bool selected;
}
for (int i = 0; i < GameObject.Find("GameManager").GetComponent<GameManager>().units.Count; i++)
{
// if (GameObject.Find("GameManager").GetComponent<GameManager>().units[i].trans == this.transform)
{
gm.GetComponent<GameManager>().units[i].selected = true;
}
}
this is the error message, i havent seen this one before some help would be nice thanks.
Assets/unit.cs(32,48): error CS1612: Cannot modify a value type return value of `System.Collections.Generic.List.this[int]'. Consider storing the value in a temporary variable
Answer by OncaLupe · Nov 28, 2015 at 09:12 PM
This has to do with how Structs are handled. They are value types so when you're accessing it from inside a list, it's actually a copy you get back, so you can't set variables inside it directly. You have three options that I know of; make 'unit' a class, use a temp variable, or create a method inside the struct to set the value.
Option one: If you replace 'struct' with 'class' in the declaration of 'unit', it will change it from a value type to a reference type, and allow you to change variables inside it directly. However, because classes are reference types, if you copy a unit (like unit[0] = unit[1]
, remember that those will point to the same object, and changing one will change the other.
Option two: Temp variable:
unit temp = gm.units [i];
temp.selected = true;
gm.units [i] = temp;
Option three: Method in struct:
[System.Serializable]
public struct unit
{
public Transform trans;
public bool selected;
public void SetSelected(bool newValue)
{
selected = newValue;
}
}
gm.units [i].SetSelected(true);
Finally, unrelated to the question, but you should try to avoid repeated use of GetComponent if possible. GetComponent is a slow operation, and can hurt performance if done often. If you need to reference an object that won't change (like game managers), it's usually a good idea to do the GetComponent once in Start and store it, then use the stored value later. Especially if using Find as well, which is also slow.
void Start()
{
gm = GameObject.Find("GameManager").GetComponent<GameManager>();
gm.FunctionCall();
}
Your answer
Follow this Question
Related Questions
How to get all children of a Gameobject with a certain component 2 Answers
List out of range on parameter index; Editor in debug shows it isn't 1 Answer
C# How to convert a struct type list into a string? 1 Answer
ArgumentOutOfRangeException: Argument is out of range error when used with for loop 1 Answer
Error in Inventory Script 1 Answer