Improving Upon Selection Highlighting in Our Game — Part 3

This is what you have to look forward to in this article!

Introduction

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:

  1. Updating the arrow model to a new one that looks more clear to the viewer
  2. Implement functionality to switch which item is selected with the Tab key
  3. Bugfixes

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 ItemSelector script.

Here, I am assigning the arrow game object to the script attached to the water pump and adjusting its placement.

Switching the Selected Item

As I’ve stated before; a lot of work just to grab the spade

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:

As the player moves around the different objects, they are automatically added and removed from the list of colliding items

Implementing Changes

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.

Yep, that seems to work!

Next, let’s write a function in the ItemDetector class that will rotate the list of colliding items and see if that works:

So far, so good!

My strategy for rotating the list forwards goes as follows;

  1. Copy the last item in the list to the top of the list.
  2. 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.
  3. 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.

According to plan!

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 RotateListAndReturnFirstItem.

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:

  1. When pressing E at 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.
  2. Sometimes when pressing Tab, the arrow just disappears. This is because the object Dock island grass is selected and that object does not have the ItemSelector script 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 functionRotateListAndReturnFirstItem to call MoveLayersToTheTopOfTheList, and I also created a new list that only contain layers 6(items) and 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 Shift + 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 Shift + Tab;

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 6(items) or 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;

This, too seem to work!

Finally, let’s implement changes to select that item and put it first in the list.

We did it! 🥳

Fixing bugs

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 ItemDetector class:

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 ReturnClosestItemByTagOrLayer;

Another one bites the dust!

The Arrow Gets Stuck When Rotating Backwards

When pressing Shift + Tab, the game stops at a certain point without going through the full list

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[0]), I will go ahead and fix that so that the list actually rotates as it should.

Rotating Forward and Backward at the Same Time

Both SwitchSelectedItem("forward") and SwitchSelectedItem("backward") are called when I press Shift + 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("forward") or 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.

Final Result

Now the system for switching back and forth between objects seem to work exactly as it should!

Conclusion

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!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store