- Home /
How to shorten multiple if statements ?
Hi everyone, long time reader first-time poster. So I'm not a super experienced coder. I was wondering if there was any way I could condense multiple if statements that check the same thing at different values.
The player can put boards onto a door to reinforce the door and raise the health of the door. When the player adds a board, the door game object activates the board model that is a child of the main object. It will deactivate the board object if the door's health is within a certain range. if the health is less than 10 all the boards are deactivated In between 10 and 13 the first two boards are the only ones active.
I was just wondering if there was any way to condense these if statements into less code. Thanks ahead of time!
void boardCheck()
{
doorHealth = doorHealthScript.CurrentHealth;
int b = 0;
if (doorHealth <= 10)
{
for (b = 0; b < 5; b++)
{
boards [b].SetActive (false);
}
}
if (doorHealth <= 13 && doorHealth > 10)
{
for (b = 2; b < 5; b++)
{
boards [b].SetActive (false);
}
}
if (doorHealth <= 16 && doorHealth > 13)
{
for (b = 4; b <= 5; b++)
{
boards [b].SetActive (false);
}
}
}
Answer by rageingnonsense · Jul 20, 2017 at 05:58 PM
For starters, you could use else if to simplify your logic:
if (doorHealth <= 10) {
for (b = 0; b < 5; b++)
{
boards [b].SetActive (false);
}
} else if (doorHealth <= 13) {
for (b = 2; b < 5; b++)
{
boards [b].SetActive (false);
}
} else if (doorHealth <= 16) {
for (b = 4; b <= 5; b++)
{
boards [b].SetActive (false);
}
}
Conceptually, you could change how you have this set up a bit. I don't know what "boards" is; but assuming just a game object. You could attach a script to each one like so:
class board {
public threshold;
}
Then you set it in the editor (or via code) to either 10, 13, or 16. then you could reduce all of your code to this:
for (b = 0; b < 5; b++)
{
if(boards[b].GetComponent<board>().threshold <= doorHealth) {
boards [b].SetActive (false);
}
}
This gives you a lot more control if you wanted to expand to more boards at a future date as well. It might be slower to call GetComponent() too often though. I am unsure. If that is the case, you could always cache them within your master class where the loops happen, in the Start() method.
NOTE: This is untested pesudocode for the most part; just wanted to get the concept across.
That looks like it could totally work. I'm going to try that. Thanks!
Obligatory LINQ one-liner:
boards.First(item => item.Threshold <= doorHealth).SetActive(false);
That does not the same. Have another look at the original code. Your code just disables the first object that matches the given condition. Also, even not specified explicitly, the collection could contain more than 5 elements and your Linq statement would cover all elements and not just the first 5. This might not be relevant here but is another difference. Don't use Linq if you do not fully understand it. It's better to write code that is easy to read / easy to follow.
If you really want a one-liner that does the same as the last example it would be:
boards.Take(5).Where(i=>i.Threshold <= doorHealth).ToList().ForEach(i=> i.gameObject.SetActive(false));
Oh shit, you're right. I just skimmed through the post, sorry.
Answer by dpoly · Jul 21, 2017 at 12:44 AM
The general answer to this question is always to turn code into data. Data structures are almost always easier to read, understand and modify, but they may take a little longer to write.
Ultimately large parts of a game should be encoded into a range of data structures, which makes future customisation far easier. You have an answer to a the small question of how to shorten the code, but think instead about how best to improve the code.