About 'For Loops'!

In this video (objectives)…

  1. Find a bug in our game which causes our standalone PC build to break.
  2. Figure out why the game is breaking because of the bug.
  3. Use a for loop to change our input mechanism and stop ArrayOutOfIndex errors.

After watching (learning outcomes)…

Fix our ArrayOutOfIndex error using a for loop for player input.

(Unique Video Reference: 16_TX_CUD)

We would love to know…

  • What you found good about this lecture?
  • What we could do better?

Remember that you can reply to this topic, or create a new topic. The easiest way to create a new topic is to follow the link in Resources. That way the topic will…

  • Be in the correct forum (for the course).
  • Be in the right sub-forum (for the section)
  • Have the correct lecture tag.

Enjoy your stay in our thriving community!

A post was split to a new topic: When do we add the Quit functionality?

I am having trouble really understanding how that For Loop actually gets us to our next states. I understand the general concepts behind the pieces of the For loop, but I can’t visualize exactly how those components come together to get us from point A to point B in terms of the next state.

If there is a way you can breakdown what the system is seeing when it runs the loop that would greatly help in understanding why that particular sequence of code works the way we need it to work.

Thank you and great course so far!

1 Like

Hi Shawn,

The for loop isn’t really getting you to the next state, it is being used to display the options which correspond to each state. The for loop is used to iterate through all of the elements in the array.

Let’s break down the ManageStates method;

private void ManageState()
{
	State[] nextStates = state.GetNextStates();

	for(int index = 0; index < nextStates.Length; index++)
	{
		if (Input.GetKeyDown(KeyCode.Alpha1 + index))
		{
			state = nextStates[index];
		}
	}

	textComponent.text = state.GetStateStory();
}

The first line of this method creates a local variable named nextStates which is declared as a State array. It is initialised on the same line using state.GetNextStates, this is the method which returns the array of states which the player can move to, for each individual state.

Next, we have the for loop.

The first line could be read like this;

  • “declare a variable and initialise it to equal zero”
  • “iterate whilst the value of the variable is still lower than the number of items in the nextStates array”
  • “increment our variable on each iteration by 1”

Within the code block for the for loop we check to see which key has been pressed. We know that our options will always be 1, 2 or 3, so we can assume that we will always start with 1, hence using the KeyCode for Alpha1, and on each iteration we add the value of index to it.

As our variable, index, was initialised to zero, the first time the for loop iterate it’s effectively saying;

  • “Use the value of KeyCode Alpha1 and add zero to it”

The result is that it is still the value of KeyCode Alpha1, e.g. 1

If that key has been pressed then the next statement is executed, this is where we set the current state to be equal to the state from our nextStates array, where the array’s element index is equal to the value of the index at that time, in this scenario it would be zero.

If that key hadn’t been pressed that statement is ignored as the if statement wasn’t true, and the for loop continues to iterate.

On the second iteration, index has been incremented to a value of 1. We again check for our player input, but this time we are saying;

  • “Use the value of KeyCode Alpha1 and add one to it”

The result is that we are checking for a KeyCode Alpha2, e.g. 2

If this condition is true, e.g. that button was pressed, the next statement is executed and the current state is set to be equal to the state from our nextStates array, where the array’s element index is equal to the value of index at that time, in this scenario that would be one.

If you have 3, 4, 5 or however many states you placed into your nextStates array, the for loop will keep going until it has been through them all, and then stop.

However, because we are calling ManageState from an Update statement, this entire method is executed over and over again.

On that note, there is also a bit of an expensive bug where we set the story text in every single frame, this can be avoided by moving that statement to be within the if statements code block, as follows;

private void ManageState()
{
	State[] nextStates = state.GetNextStates();

	for(int index = 0; index < nextStates.Length; index++)
	{
		if (Input.GetKeyDown(KeyCode.Alpha1 + index))
		{
			state = nextStates[index];
			
			textComponent.text = state.GetStateStory();
		}
	}
}

In the above, rather than setting the same text every single frame, it gets set once and then only changes when the player selects a relevant option.

I hope the above makes sense, if anything is unclear please let me know :slight_smile:

1 Like

Hi Rob,

Yes! Thank you so much for that I totally understand it now.

1 Like

Awesome! Happy to help :slight_smile:

The change to a for loop has introduced a possible bug or maybe undesirable functionality. We’ve ended up back in the situation where multiple keys being pressed at the same time will take all of them into account. So in the case of the loop, it will always be the last key detected that will take precedence. That’s ok if that is what intended but it might make more sense to add a ‘break’ statement to the loop so it breaks out on the first key down detected.

I have a concern about the implementation, it will be inefficient as more next states are defined inside of each state because we are iterating over all next states every time a key is pressed. Is there a better way of do it? for example get directly the input key code instead of using the if statement, and use it to get the state on that index (of course the key code should be validated as an int and be less than the total next statements). Is this possible in Unity?