Unity New Input System (part 2)
Challenge: Converting Old Input System to New Input System
Continuing from the previous article (which can be found here) in this article we will start replacing the old input system with the new input system.
For this project, I decided to make use of an “Input Manager” class which will house all of the input functions within. This process allows for a better organized structure later on once we start adding more Action Maps. (such has Vehicle controls and Menu Controls)
Creating the Input Manager:
So to start, we are first going to create an new C# script called “Input Manager”. Then we are going to create an empty game object within the scene which will house this Input Manager script.
Then within the Input Manager script we are first going to gain access to the Input System library, by using the Unity Engine Input System. Then we will need to gain access to the Action Map script which we generated a script for in the previous article. So in the top of the script we will assgin the Game Input Actions (which is the name I gave for my Input Action Maps) to an local name called “input Actions”.
Next, following from what we have learned in activating the Action Maps of the Input Actions, we need to initialize the input Actions to gain control of them.
Therefore within an new private method called “Initialized ()” I decided to assign a new Game Input Actions to the local input Action variable. Then also Enable the “Player” Action Map. If I don’t enable the Player Action map, then I am not able to read the bindings that I have assigned. (aka. Movement using the WASD keys).
This new private method called “Initialized ()” will then be called on the start method, that way we are certain that the Action Maps are called before anything else can happen.
Next we are going create two more functions within the “Initialized ()” method, which are the preformed and cancel state when the Player Movement is triggered. (aka. when we press any WASD key, there will be movement, and when we stop pressing, there won’t be any movement)
For the Cancelled state, we are basically going to do nothing, since there shouldn’t be any movement when nothing is pressed. Therefore we will assign an public method called “InputMovement” with an Vector3.zero as the variable.
Don’t worry if there is an error, this is because we haven’t created the public method from the player script yet. Once we do that, the error will go away.
Before we can move to the Player script and solve this issue we are first going to add in the performed action. In this performed action we are going to do a “Read Value” which makes Unity read the current value of both X and Y axis. The value being recalled back from unity will determined the direction which the player show move in. (aka an -x value means “left” while a positive x value is “right” etc.)
The Player Script:
To solve the error that is happening on the Input Manager script, we just need to create an new public method within the player script using the same namespace that we provided. (in this case we used the namespace “InputMovement”.
As you can see, within the Input Movement method, I already added a local variable called _move which equals the vector3 input value. This “_move” is private local vector3 variable which I assigned within the Player script.
So now I have the input values of my X and Y axis from the Input Manager which is then being pulled to the player script so it can be then applied to the movement method that was native within the Player script.
The good thing about converting old input system to the new input system is that you technically don’t have to adjust much of the script. I can take the pre-existing script and make it read from the newly created “_move” variable and they won’t be much else to change.
It just happens so that the script provided by the client already has a “Calculate Movement” method that required an X and Y axis variable. In this scenario I have to do is to swap both the float’s H and V value to the “_move” value and we are done.
We can test this out quickly by saving the current script and playing within Unity.
As you can see, now the player is able to move forward and backward along with side to side normally with the new input system.
The Interactive Zone Script:
Now that the movement function is completed, we can move on to the next step which is creating the collect and action function. During the inital play through of the prototype, we noticed that the game requires the player to be able to collect objects and also be able to use those objects with an action toggle. This action toggle is also able to trigger events within the interactive zones.
According to the old input system script, the desired key binding to toggle the action and collect function is the “E” key. Therefore in the Action Map we are going to add that Action into the Player Action Map.
According to how the scripts are structured, we have an player script which controls the player, and also an Interactable Zone script which controls what event zone the player is currently in contact with. The Interactable Zone script is also in control of the player collect and action toggle function. Therefore instead of using the Input Manager to call upon these actions, it is much quicker to just have the input actions be called within the Interactable Zone script directly.
So just like how we setup the Input System within the Input Manager, we are going to follow the same structure within the Interactable Zone script.
Since the script already has private Enums of the zone type already named, we know that we have to divide 3 actions within the Input System.
Enum Colletable = Input Actions “Collect”
Enum Action = Input Actions “Action”
Enum Hold Action = Input Actions “Hold”
Next we just need to do the scripts for the Collect performed and Action preformed function like we have done with the Input Manager script.
Since there is a Hold function, we will need to implement the started and canceled function. So whenever there is a tap, that will trigger an cancel function, and whenever the button is pressed and hold for more than the desired duration, it will be considered an hold function.
ie. Tap = canceled
Hold = started
Since the previous script already has the proper functions written and is function, we don’t need to touch or edit them in any way. What we do need is to make sure they are divided into the proper preformed function (aka, collect, action and or hold)
Once that is done we can test out the functions by playing the prototype.
Since the Interactable Zone script is functioning it means that the player is able to traverse the game zone one by one. The next obstacle that the player encounters would be the Drone.
Input Manager Script:
For the Drone and other vehicles which the player will encounter we will be controlling all input functions via the Input Manager, that way we can have a more organized and easier debugging control. But before we can start scripting with the Drone script, we must create the key bindings within the Action Map.
Just like the setup that we used for the Player, the control bindings are similar for the Drone, we will need Movement, Rotation, Flight (which controls the up and down movement) and the “Escape” button which will allow the Drone control to exit and revert back to the player controls.
To be able to have the Input Manager communicate with the Drone script, we are first going to need the Input Manager to gain access to the Drone script.
In this point in time we can even plan ahead and list all the required scripts which the Input Manager would required such as the Fork Lift or Crate script.
Next within the Input Manager I create a public method (which the Drone script can access) that allows the Input System to swap controls from player to Drone. This is done by disabling and enabling the Action Map.
There is another method called “Flying” that is used within this public method. This flying method is what controls the performed inputs.
Then within each performed input function we will do a read value so we can pass in the value to the drone script. We will need to write an public method within the drone script (of course this isn’t done yet so there will be errors). For the Canceled functions we will pass in the value of zero, since we don’t want anythig to happen when the button is not pressed.
Back in the Drone script there are several things that we must add before we can make the connection between Input Manager and the Drone script. First we will need access to the Input Manager. Then we are going to create 3 private local variables (2 Vector3 and 1 float value).
These values are going to allow the values from the Input Manager be pass into the Drone script. Just like how we setup the Player script, we will do so the same within the Drone script. We start by creating an public method that is able to pass in the desired value (aka Vector3 or float) then we assign that passed in value with the local value we setup previously.
We do this for all 3 local variables (aka _move, _rotation and _height).
Then within the original methods for movement, rotation, and height controls, we basically pass in the new values that we are getting from the Input Manager to control the drone movement.
Since we are only passing in the values, the main functionality of the methods are not touched. This make swapping to the new Input System much more streamline and easy.
When we head back to Unity to test out the Drone function, we can see that it works perfectly.
One thing we forgot is the escape key function, we have implemented the key binding and it is active within our Input script, the only thing missing is the performed action. To quickly finish this, we are going to create a public method within the Drone Script and name it “Cancel Flight Mode”. Since the original script has this function already, we can simply copy and paste the content into this new public method.
Now all we have to do is call this public method within the Input Manager script whenever the escape key binding has been performed.
Working with Other Scripts:
Since we have a proper understanding how to incorporate the Input Manager with the existing scripts, the rest of the scripts can easily be finished by replicating the same procedures from converting the Drone script.
As long as the Input Manager is providing the input values, all you have to focus on is passing those values into a local variable within the required script (aka, Fork Lift or Drone, or Laptop, or even Crate scripts). The existing functionality of those scripts are usually left untouched.