Improving Upon Selection Highlighting in Our Game — Part 3
This article is about the development process of our first game. During the process, we are learning how to use Unity & Blender from scratch to create everything you see in the article, enjoy!
Welcome back to the third and final installment of improving the selection system. In the last article we looked at some minor improvements and bug fixes and in this article, I will finish the implementation so that we can continue with the vehicle system in the next part.
This time I will focus on the following 3 things:
- Updating the arrow model to a new one that looks more clear to the viewer
- Implement functionality to switch which item is selected with the
Updating the Arrow Model
We have updated the arrow model to a new one that should look more clear to the viewer.
To implement it, I’m going to select the game object as the value for the appropiate variable in the
Switching the Selected Item
I want to update the functionality of the selection system so that when you have a bunch of items in front of you, you should be able to pick which one is selected by pressing
Tab so that you don’t have to move all other items out of the way first.
The Current Functionality
When you get in range of an item that can be interacted with, that item is added to a list of items that can be interacted with.
If you come into contact with more items, they are placed at the bottom of the list.
Should an item go out of range, they will automatically be removed from the list, and if the item at the top of the list is removed, all other items will move one step up in the list, item #2 will be number #1 and the selection arrow will hover above the new #1 instead.
Let’s see how this works in action:
The functionality that I want to enable should rotate the list by one step so that the item at the top of the list is added to the bottom, and everything else moves up a step when you press
Tab, and vice versa in the other direction when you press
Shift + Tab.
For the first step, I will create a function that is called when pressing
Tab. I’m going to place it in the class
CharacterInteractions since all the other functions that are called by using the keyboard and mouse controls are in there already.
Next, let’s write a function in the
ItemDetector class that will rotate the list of colliding items and see if that works:
My strategy for rotating the list forwards goes as follows;
- Copy the last item in the list to the top of the list.
- The 1st item in the list should be automatically moved to the 2nd position, the 2nd item will be moved to the 3rd position, and so on.
- Remove the original item from step 1 at the bottom of the list from the list.
These steps will be the same, except in reverse when rotating the list backward.
Let’s try implement my theory in code and see if it works.
After rotating the list, the next step will be to set the variable
selectedItem to the first item in the list the and spawn the arrow above it.
Before I do that, I will refactor
RotateList a bit and rename it to
After refactoring, I will update the function call of
RotateListAndReturnFirstItem to set
selectedItem to the first item in the list.
Let’s try out the code and see if it works!
It didn’t work exactly as I wanted on the first attempt, here are some issues that has to be fixed:
- When pressing
Eat the end of the video, the watering can is picked up even though the spade is selected. Therefore, I have to make sure that the selected item actually is the one that will be picked up.
- Sometimes when pressing
Tab, the arrow just disappears. This is because the object
Dock island grassis selected and that object does not have the
ItemSelectorscript attached to it, but it is still necessary to be in the list for the sake of other functionality. To fix this problem, the script will have to skip items that cannot be interacted with and move them to the bottom of the list.
The Wrong Item Gets Picked Up
Let’s look at what the function for selecting which item to pick up looks like before we try and fix the problem.
If we look at line
7, it says
selectedItem = itemDetector.ReturnClosestItemByTagOrLayer("tag", itemType);.
This means that when I select something by pressing
Tab, and then try to pick it up, the line of code above is called which disregards which item is already selected and just picks the closest item to the player.
I commented out the line that I mentioned above and now it picks up the one that is selected, easy peasy!
Ignoring Items That Cannot Be Picked Up
As you have probably seen in the videos above, the game object for the island itself is also selected when pressing
Tab to switch the selected item, which is a problem. I want the function to put the items that cannot be picked up at the bottom of the list automatically.
I will begin by writing a function to move items of certain layers to the top of the list so that all other layers are not selectable;
I updated the function
RotateListAndReturnFirstItem to call
MoveLayersToTheTopOfTheList, and I also created a new list that only contain layers
10(vehicles) to pass to that function.
I also made sure that the function call for
RotateListAndReturnFirstItem can’t be run when an item is equipped so that you have to drop whatever you are carrying before selecting something new to interact with.
As you can see, the game now only selects items that can be picked up and ignores the rest.
Doing it in reverse
Now that we have successfully implemented a way to switch which item is selected in one direction, let’s also make it possible to press
Tab and go in the other direction.
The reason for wanting to be able to go through the list in the other direction is to allow players to go back in the case that they go too far and don’t want to go through all other items in the list that are (for the moment) irrelevant.
I will begin by implementing the trigger for pressing
When going from the back of the list to the front, we have to remember that we are already placing all items that do not belong to layers
10(vehicles) at the back of the list.
This means that I cannot just pick the last item of the list and put them first to rotate the list without running into the same problem as before. Instead, I will try to loop through the list in reverse and find the last item in the list that can be interacted with and put that first. Before I begin, I’ll see if I can get the loop to go through the list in reverse.
Let’s modify the code to print out the last item in the list that is selectable, to make sure that the correct item will be selected;
Finally, let’s implement changes to select that item and put it first in the list.
Now that all the feature are implemented, let’s fix the bugs before we call it a day.
The Water Pump Is Selected When Dropping the Spade
For some reason, the water pump is selected when you drop the spade, but it should only be selectable when you are carrying a watering can.
The problem is caused by the following line in the function
OnTriggerEnter in the
When I select an item that comes within range, I need to write an
if case to make sure not to select the water pump unless the player is carrying the watering can.
I added the
if case to
The Arrow Gets Stuck When Rotating Backwards
The code for rotating forward seem to work, but not the code for rotating backward. Let’s take another look at how the code is written;
If we look closer at the code, there are a couple of mistakes that might help explain the problem.
Not Rotating the List
If you look at line
20 above, it looks like I am inserting the first item in the list… in the same position it’s already in.
It should of course be
collidingItems.Insert(0, collidingItems[i]), not
collidingItems.Insert(0, collidingItems), I will go ahead and fix that so that the list actually rotates as it should.
Rotating Forward and Backward at the Same Time
SwitchSelectedItem("backward") are called when I press
Tab because the only condition for
SwitchSelectedItem("forward") is that
Tab is pressed.
I changed the code and now it is only possible to call either
SwitchSelectedItem("backward"), but not both;
Removing the Wrong Item When Rotating the List
If you look at line
9, it says
collidingItems.RemoveAt(i - 1);. This line determines which item to remove after adding it to the top of the list so that there are no duplicates in the list.
Unfortunately, I thought about the index to be removed incorrectly, and the index of the item to be removed should be
i + 1 instead. This is because the index of the original item has moved down 1 position(
i + 1) because we add 1 item(
+ 1) to the top of the list.
Now the system for switching back and forth between objects seem to work exactly as it should!
Thank you so much for reading all the way to the end, this article got way longer than I thought it would.
Now I am finally done with item selection and can continue with implementing the vehicle system in the next part.
Let me know if you have any thoughts or questions about our game in the comments!