- Home /
Using Arrays to Organize Variables
I have some code that is working well, but I would like to optimize and organize it. I am new to C# and do not yet know the best practices, so here is an example of something short I have written that I would like to ask a few questions about.
The piece of code manages three stats (say Food, Hunger, and Damage) and sends updates on their values to Sliders F,H, and D to keep them displaying the proper values. At three different intervals, I want to be able to call these numbers to "tick" down, so I tried to make a generalized "tickStat" function. At first I had each stat in its own field and I tried to pass a reference to that variable into the function so that it could be ticked down appropriately, but then I found that you cannot pass references in C#. On this board, it was advised to use arrays to keep track of the similar stats and to use an index to choose which stat to effect (as in the code below). Is this the best way to go about what I want to do? Is there a way to organize things so that they are conceptually grouped by Stat?
You can also see that I did not do this array refactoring for the public Slider fields. I could not figure out how to properly declare an array of Sliders. I could also use help on that :)
enum stat {f, h, d};
private Slider[] sliders;
private float[] tickRates;
private float[] tickAmounts;
private float[] totals;
private float[] currents;
public Slider sliderF;
public Slider sliderH;
public Slider sliderD;
void InitializeStatArrays()
{
sliders = new Slider[] {sliderF, sliderH, sliderD};
tickRates = new float[] {.5f, 1.0f, 2.0f};
tickAmounts = new float[] {1f, 1f, 1f};
totals = new float [] {100f, 100f, 100f};
currents = new float[] {100f, 100f, 100f};
}
void Start () {
InitializeStatArrays();
StartCoroutine(tickStat((int)stat.f, sliders[(int)stat.f], tickAmounts[(int)stat.f], tickRates[(int)stat.f]));
StartCoroutine(tickStat((int)stat.h, sliders[(int)stat.h], tickAmounts[(int)stat.h], tickRates[(int)stat.h]));
StartCoroutine(tickStat((int)stat.d, sliders[(int)stat.d], tickAmounts[(int)stat.d], tickRates[(int)stat.d]));
}
IEnumerator tickStat(int thisStat, Slider thisSlider, float thisMuch, float thisManySeconds)
{
while (currents[thisStat] > 0f)
{
currents[thisStat] -= thisMuch;
thisSlider.value = currents[thisStat];
yield return new WaitForSeconds(thisManySeconds);
}
}
First of all, yes you can pass references in C#. If you mean value types, that's what the ref keyword is for.
You could create one struct holding information necessary for the coroutine to run. Create three instances of it and run your coroutine 3 times passing one struct each.
Answer by TheSOULDev · Sep 20, 2017 at 08:59 PM
You can send references as arguments, just use the ref keyword. The way you declare an array of sliders is the same as every other array declaration: Slider[]
, which you have in your code.
The way you're doing this is of course not the best way of doing it (Hell, arrays are like the 2nd worst way to do it), as that would probably be creating a class to hold the values you need, and then declare the functions that will use them. That would also group them by Stat, if the class you declared them in was called Stat.
More on classes here: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/classes
Answer by unit_nick · Sep 21, 2017 at 05:48 AM
how about a list of stats?
private List<Stat> stats;
class Stat
{
private float _time;
private float _rate;
private Slider _slider;
public Stat(string name, float value, float time, float rate)
{
_time = time;
_rate = rate;
foreach (Selectable selectableUI in Selectable.allSelectables)
{
if (selectableUI.name == name)
{
_slider = (Slider)selectableUI;
_slider.value = _slider.maxValue = value;
}
}
}
public IEnumerator Tick()
{
// possible that slider not found so check for null
while (_slider != null && _slider.value > _slider.minValue)
{
_slider.value = Mathf.Max(_slider.value - _rate, _slider.minValue);
yield return new WaitForSeconds(_time);
}
}
}
private void Start()
{
stats = new List<Stat>();
// create a stat for the slider. name (must match name in editor), max/initial value, update time, update rate
stats.Add(new Stat("SliderF", 100f, 1f, 0.5f));
stats.Add(new Stat("SliderH", 100f, 1f, 1f));
stats.Add(new Stat("SliderD", 100f, 1f, 2f));
foreach (Stat stat in stats)
{
StartCoroutine(stat.Tick());
}
}
Your answer
Follow this Question
Related Questions
Game architecture problem 0 Answers
MergeSort function acting strange 0 Answers
Random Color Array material turns white 1 Answer
How to add an array to monobehaviour 1 Answer