♪ [MUSIC] ♪ [ANDY] Hello, folks, this is going
to be a Unite Now webinar on the Unity Input System. This webinar is going
to be a bit different to the last time we spoke
about the input system in that it's going
to focus on workflow tips and feature integrations. The last webinar that we did,
which was Meet the Developers, covered more of the fundamentals
of the input system and showed how to set up
a base character interaction system where you could run around,
and you could attack with a sword. You can watch that
on the Unity YouTube channel. My name is Andy Touch.
I'm a Senior Content Developer at Unity Technologies.
My job is to use Unity and use the new features
that come with the engine and demonstrate how
they're made, make examples, and show you how you can use
Unity in your own projects. As a summary, Unity
has a newish input system. I say newish because
it's been a verified package or a verified feature
for a little while now. It's our solution to setting up
cross-platform input for Unity projects. It's a verified package
in Unity 2019 LTS. It comprises of several things,
such as an Asset, an interface, component,
and API workflows. As you can see here
in these screenshots, on the far left, we can see here that we can create
an Input Actions Asset. This Asset then has an interface, a window, which allows you
to set up your control schemes, such as Player, Menu,
Vehicle Controls. What actions those contain, such
the player has movement and attack, and vehicles could have
accelerate and steer. Then you can use
a Player Input component, which takes these actions,
then instances them in the Scene. Then once it instances
them in the Scene, and it can be read at runtime, you
can then apply that to your game. For example, if you had
an attack action, you can use a playerInput
component in a Scene to register when that attack
is taking place, then apply some code to it, such
as swing a sword on a character or play a sound effect. I've created an example project
called Warriors. This is available today
publicly on GitHub. There's a link at the bottom. Warriors is an example project,
which covers a wide variety of different uses
of Unity's Input System. This ranges
from cross-platform inputs, such as gamepads on console,
keyboard and mouse, and touchscreen all the way
through to rebinding UI. I'm going to be using this
Warriors project in this webinar to demonstrate several workflow
features that I'm going to cover, from feature integrations,
such as UGUI and Cinemachine, to also how to do
things, like rebind UI and detect when a gamepad
is unplugged and re-plugged again. If I now switch over to Unity... Let's take a look at this project. When you download the project,
you have this example Scene, which has several
different components or several different objects
in the Hierarchy. We have this centralized
GameManager, which allows you to switch
between Single Player and Local Multiplayer mode. In Single Player,
when you click Play, you'll be able to take control
of this warrior character. Using keyboard, you'll
be able to move around and also swing your sword. This character controller is driven
using the Unity Input System. Here, we have player controls, which has actions for Movement,
Look, Attack, and TogglePause, like so. Each of these actions is comprised
of several different bindings because you may create
a game for cross-platform, one that runs on a touchscreen, one that runs
on different forms of consoles: desktop, VR, anything
that you want to target. Movement has a binding of WASD,
arrow keys, so I'm controlling it with a keyboard like so to move
the character around. Also a binding
of a left stick of a gamepad. If I pick up
this PlayStation controller, I can then control the character
using the exact same code base. I haven't actually changed
any of the code to say, "If using PlayStation, do this,"
it's all automatic. It's all pretty generic
in the code. It just takes whatever gamepad
is set up here, whatever input device
is set up here and funnels it in. I can even pick up
an Xbox controller, and UI will now update and run around with that as well. So it's very automatic.
It switches gamepads very easily. You can create all kinds
of different action maps' actions and bind it to all kinds
of different devices. As mentioned earlier,
the previous Unite Now webinar covers a lot of this setup. I went through the process
of creating an action map, setting up these actions
and these bindings, and then hooking that
into the code. You can watch that video
to go over that if you're not familiar
with the system. We can continue watching this video
to see how the input system fits into different workflows
and scenarios that you may come across
or you probably will come across when creating
your games and projects. This Warriors project also includes
a local multiplayer mode. This takes
this warrior Prefab instance and it spawns using Instantiate
multiple at runtime. So as I hit Play, it takes
that warrior that's in the Scene, removes it, and spawns
four instances from a Prefab. Each of these has the Player Input
component, as you can see here. Each of them is using
this very same InputActions Asset, but it's instead getting the events of these different
bindings and actions and using them locally. Using the Unity Input System, you can not only set up very
visually these inputs and bindings, but you can also use it flexibly to
create things like local multiplayer. I can move using my keyboard keys. I can run around with the keyboard and also
the PlayStation controller. I'm doing this all by myself, so it's a bit tricky to run around
with these characters. I need more hands and fingers, as you can see in this project. You can create local multiplayer,
you can create cross-platform control schemes, you can create them
more visually as well. Let's cut back to the slides. As I said, you can download
that project now, it's public. I'm going to keep updating
and improving this project, so you might see
that there is a version 1 for the previous webinar, version 2 for this webinar, and
I'll be doing bug fixes and things, so if you find any issues,
you can file them as an issue, and then I'll look into it. I'll also be adding
extra features and functionality in this example scenario as they are released
with the input system in future releases. Let's talk about one
of these scenarios. This one is Switching
Control Styles. In a typical game,
you'll have a set of controls. In this case, character controls. This is a reference
from Grand Theft Auto 5 made by Rockstar Games. This is not a Unity project,
but I'll be using it as an example scenario. In a game like this, you would
have a set of character controls where you use a joystick
to move around, use, perhaps, the X button to jump,
use a trigger to aim. You may use another
trigger button to shoot. You have this kind
of control scheme for third person on foot
control scheme. But in most games, you often have
other types of control schemes that you'll switch to at runtime or when you go between
different scenes and scenarios. In this particular game, you can
switch from this on-foot controls to vehicle controls. Obviously, you come
into some complexity here. The X button on character controls
could be a jump. But the X button on a vehicle
controls would be an accelerate. So you've got very different
types of functionality in play, but using the same
input method on your device. This obviously grows in complexity as you add more different types
of control styles, so you not only have
on-foot controls, vehicle controls
but also UI controls. An X button, which would
be jump in character accelerate in a vehicle, would, in UI, be very different
and just accept or confirm a button or an option
that you've selected in the UI. This obviously increases for other
things, such as inventory systems, weapon selection, settings menu, if you have other types
of vehicles... the list goes on. So how do you set up
in the Unity Input System different types of control schemes
and switch between them easily? In the input action Assets, you can create a series
of different action maps. As you can see here on the left,
we have Player Controls, Menu Controls, Vehicle Controls, and a couple
of different scenarios. On that Player Input component, which is basically
the instance in the Scene of this InputActions Asset,
you can set a default map. This is basically
what the Player Input is going to start with when you run the game
or you run the Scene. In this case, Player Controls. Of course, you can switch this
between different maps. For example, most games
start up with a UI menu not necessarily
directly in gameplay, so you could have the default map
as being menu controls to start with. Each of these action maps
can have different sets of actions. As you can see here,
Player Controls at the top has Movement, Look,
Attack, and TogglePause. These are all contextual
based on Player Controls. Menu Controls don't have
the same actions. They have things like Navigate,
Left Click, Pointer, Submit, Cancel. Things to do
with navigating the UI, which I'll go into
a little bit later on. They're very different types
of actions, but you might have
similar bindings. For example, a movement
of a character will use a left stick
on a gamepad to run around, whereas navigating through the UI or navigating through a menu will also use the gamepad
left stick as well. You have a lot of crossover
in different types of bindings. Once you have
your different Action Map set up via this API, it's very simple. We can reference
the playerInput component. You can use SwitchCurrentActionMap to switch to the Action Map. It's very simple
and very straightforward. After you set this up,
you can then switch to it and then bring in the actions
as they're happening and apply to your game code. If I switch back
to this Warriors project, I use exactly this to switch
between Player Controls, which is the warrior
running around and attacking, and Menu Controls to navigate
through a different UI. As I hit the Play button, we spawn all these different
instances of these warriors, and we've got
the PlayStation controller. This warrior is currently using
the Player Controls Action Map. However, when I push
the Start button, which is this little
TogglePause option here, Start [Gamepad] or P [Keyboard], it basically switches
the warrior to use the Menu Controls Action Map. If I pause, it then switches back. You can preview
this happening directly inside this Input Debug window. If I navigate to the instance
of Player Input that's using the DualShock controller,
which is this one here, User #1, and open up the Actions,
where you'll notice that we've got Player Actions for
Movement, Look, Attack, and TogglePause. Then we've got the menu ones,
which are disabled. Notice as I pause the game, it disables the Player Controls
and switches to the Menu Controls. This is using an API called, I think, it's Active
or DeactivateInputControls. Using that API
SwitchCurrentActionMap, you can switch between
these different control schemes. Using that activate
and DeactivatePlayerInput, you can also turn on
different sets on and off. The next scenario I want to talk
about is navigating UI interfaces. in this specific case,
it's UGUI, Unity's UI system. In a typical UI system,
you often have lots of many different buttons, sliders, toggles,
and elements on the screen. In this specific reference,
which is <i>Legend of Zelda,</i> <i>Breath of Fire</i> by Nintendo,
this isn't a Unity game, but it's a great example of having
explicit navigation for a list, so you push up on your gamepad or your arrow keys and it basically
navigates up a list or down a list, pushing right and left or down, and you navigate
through directional navigation, such as like a grid of items. This is quite typical in an RPG. Also, a typical button press
where you select a certain option or you hover over it with your mouse
and you click it and you confirm it. This is pretty typical. Most games
have this type of UI-style navigation. Of course, how do we actually
set this up to work in Unity, especially to make it
cross-platform and especially to navigate
these different UI interfaces, depending on what type
of device you have selected. If I go to this Menu Controls
Action Map, which I showed you
a little bit earlier on, there's a series of actions
I've already set up: Navigate, Left Click, Point, Submit,
Cancel, and TogglePause. This is just a couple
that you could have. You'll notice that I set up
a range of different bindings for each type of action, so navigating the UI, you can navigate through
arrow keys, WASD keys, D-pad on a gamepad gamepad left stick
and gamepad right stick. Then you also have elements,
such as Submit and Cancel, which would be like
an X button or a Pause button. If you use the Unity UI system, you
have this thing called an Event System, which handles all the events
that are currently being processed and applies it to the UI. With this, you can have
an Input Module. When you install
the Input System package, it basically comes with this
Input Module that you can assign. You have this very attractively
named Input System UI Input Module, which will pop up as an option or is automatic, depending
on your version of Unity, alongside the Event System. What you'll notice in here is that
you can then choose an Action Asset to assign to it,
in this case, Input Actions, and you can correspond
these bindings to different options
to navigate the UI. Now, if you actually create
an Event System from scratch or you assign this Input System
UI Input Module component, there's already a default Input
Action Asset set up for all of this. But I want to show you,
in this webinar, how you can use a custom Action Map,
in this case, this Menu Controls, and apply it to certain options. You can see here, Navigate, to move around the UI
and select different options is associated with Move, and Submit is associated
with Submit as well. Now, once you have this set up, so all this data
from the Action Asset is fed into the Event System, it then automatically works
with things, such as Interactable components. The best example is a button. When you navigate,
and you highlight a button, it switches to a highlighted color. When you click a button
or you submit, it will then process
this On Click event, and it factors in
stuff like the Navigation, so you have a Horizontal,
Vertical, and Automatic navigation. I might be overcomplicating things,
but this just happens automatically. It's basically saying
that as long as this is all set up in the Event System,
from this Input Action Asset, it'll work automatically
with Interactable elements, such as buttons, sliders,
scroll bars, and things like that in the Unity UGUI system. If I switch over to Unity,
let's show that in work. If I go over to my Event System, you notice here that I've already
got the Input Actions set up from that Input Action Asset. But if I added
this Input System UI Input Module, imagine I'm just adding
a brand-new one from scratch, we've got here
this default Input Actions, which is already set up with all
the things like UI Point and Click, so you don't actually have to
create this brand-new Action Map. You can add this component, it's
all automatically set up for you. But, of course, in this demo,
I want to show you how you can use your custom sort of actions
or your own specific Action Map. If I switch to the Game Manager
and go to Single Player and click Play, obviously, you can run around
with my character. When I push that TogglePause option
in Player Controls, I'll then switch into the UI. As I move up and down
with my joystick, I can navigate between
these different elements, and I can press the X button to confirm and choose
these different types of panels. I can also navigate left and right to
move to this Rebind Control System. If I switch over to my keyboard,
and I pause the game, I can actually use up and down
in the WASD and arrow keys and enter to have basically
the same functionality. In the code, I haven't
actually changed anything or done anything exotic or unique. As long as that Event System has
these actions and bindings set up, it will just work automatically
with the Unity UI system. They also detect
mouse hover over states and also things like if you built
to a touch screen device, tap is a submit or a left-click, and your finger
is where the pointer would be. That's the Unity UI system
in a nutshell and how the Input System
can tie into it. Controlling Cinemachine. In most games, you often have
a camera that follows a particular target. Most cases is a character,
but it also could be a vehicle or kind of anything
that's tracked in the Scene. In this particular scenario
of, say, an orbit camera, you have this camera
that follows this character, but you also control it, so you
have that automatic element of it following and being a certain
distance from your character that's moving around,
but you also control it. You push left
or some kind of X input, and it orbits around the character, but then you have
some value in the Y-axis, which is then going to move
the camera up and down, not flip over entirely,
but it's going to go up to a certain top degree and to a certain lower degree,
whereas the X is more free form. This is a typical
orbit camera setup. You want to take your X and Y data, which is probably going
to be a mouse and joystick or a mouse and joystick here. That joystick could be on a gamepad
or a virtual joystick as well. You want to feed that
into Cinemachine. Unity's camera system, Cinemachine,
does this stuff automatically. But you need to feed your data
from the Input System and from your actions and bindings
directly into these values. So, I won't go through
all these elements of Cinemachine. I'll just go through the scenario
that's in this Warriors project, which you can download
and dissect a lot further yourself. But in Cinemachine,
when you install it and you have this list
of different types of cameras, if you go to a FreeLook
Camera, it will create this free-look camera
circular or spherical rig. You've got tons of options here.
I won't go through all of them. But the main ones that you want
to have a look at is Y and X here. The X-Axis value is going to orbit
the camera around the warrior or around your car or spaceship
or whatever it may be and the Y value is going
to move it up and down on this bar, so when you push,
say, a joystick up, it's going to go to the top
or it's going to go down, depending if you like
inverted control schemes or not. You need to get your data
from your mouse, your finger,
your left stick gamepad, or your D-pad
on your gamepad as well and feed it
into this X and Y value. How do you get data from this? Here, we have
this action called Look, and Look gets the bindings
of delta of the mouse as the mouse moves in a
particular direction on the screen and also the right stick
of any gamepad, whether it's PlayStation,
Nintendo, Xbox, or any other gamepad that is
compatible with the Input System. How do we actually get
this Look Action and assign it to these values? Because Look is going
to return a Vector 2 over which direction
the keys are being pushed. We're going to take
the Y and the X from Vector 2 and feed it into these values. Cinemachine automatically
has a component that you can use that does this. This is called
the Cinemachine Input Provider. You can obviously open up the
script and see what it does inside. What it does is it allows
you to assign an action with, say, a Vector 2
or a compatible set of data and feed it into the X-, Y-axis,
and also the Z-axis. When the Cinemachine Input Provider
is attached to a Cinemachine camera, it will feed that data in
automatically, so you don't have to write any
extra code or do anything like that. You can just add this component, point it from Look, or whatever
your desired action is, into here, and then it will feed it
to this Y and this X value. I go into the Warriors project. In Single Player, you'll notice that there's a Single Player Camera
of Stationery, which when I enter Play Mode, the virtual Cinemachine camera is
stationary, the character runs around, and this would be similar
to local multiplayer game like <i>Mario Party,</i> or <i>Overcooked,</i>
or something like that. But if I switch from Stationary
to Follow And Orbit and into Play Mode, it's actually going to use
a Cinemachine FreeLook Camera. You can actually go
to the Camera section and select them here
and be able to view this free look and see all the settings
I've already set. I won't go through all them because
I will take a couple of hours. I'm supposed
to be focusing on input. What we've got here
is we've got our warrior. Notice it's using the keyboard. The UI is displaying what
current input device it's using. As I move my cursor
to the left and right of the screen and up and down, it's basically applying that logic to that Cinemachine data. If I push the arrow keys, it's then going to obviously move
around the character, but that Cinemachine look of me moving around
with the mouse position or if I go down
to the Player Controls, the delta mass position is going to
look in the direction that I want. So it's tying that input
into Cinemachine. If I pick up my PlayStation
controller and run around, obviously left stick applies
to the movement. Now, I move my right stick. As you can see, the right stick
is tied to that Look action. You'll notice it's applying
the same logic. If I push up and down
with right stick, it's now going
to move the tilt in Y. If I push right and left
with the joystick, it's actually going
to rotate the camera. Of course, if I pick up
my Xbox controller, it's going to do
the exact same logic as well. This is how you would get data from this Input System
and the actions and feed it directly
into Cinemachine. You'll notice here if I run around as I move the camera and settings, you'll notice that these
Input Access values are changing. You can see that the data
is being fed in from the Input System
into Cinemachine. Switch back to the slides. Runtime rebinding. This is
a big request or a big scenario. I've got to mention
that all of these scenarios are ones that I've read online
or read on the forums or read in YouTube comments
or read on Twitter. It's kind of key common things
that are popping up. This list is by no means
every request or every element in the grand scheme of Input
because that's a very long list. But these are the main
big ones that I can tackle, and then in the future,
hopefully tackle other ones. One of the main big questions was
how do we set up runtime rebinding with the Unity Input System? As an example, in the recently
released <i>Spelunky 2</i> by Mossmouth, it's a game I've been playing
quite a lot recently, and I love it and enjoy it. But pretty much any game
released on console or a major release on Steam
or any other platform will have some kind
of runtime rebinding like this. You have a list of different
controls for different things, so jump is X, attack is square, bomb is circle, triangle is rope,
and things like that. Most of these games, I think pretty much all of them,
on console as well, will have some kind
of rebind system. This means that you can take
the instance of jump, which is X, so you push X to make
the character jump through the air. It's kind of self-explanatory. You can then rebind that or listen out
for another button to use because maybe you don't want
to use X, maybe you want to use right trigger, or you want
to use left trigger, or maybe you're using a control that's more suited
for accessibility. Obviously, we have PlayStation,
Xbox, Nintendo controllers, but there's many more different
types of controllers out there, including ones that allow
for better accessibility for people who may not be able
to use these controllers in the same way as other people, so maybe you want to rebind jump
to something that's easier to push or is a lot suited for your hands or your input method
you're going to use. Runtime rebinding is very important
to make your games more dynamic but also make them more
appliable and controllable by many more people out there. In this workflow,
you have three steps. One is whatever the binding currently
is, in this case, Jump is X. Two is Jump, and it's listening out
for a button to be rebound to. Next is Jump, and in this scenario,
it's been set to R2. You have the scenario where you have
to support many types of controllers. This is just three of them,
but there's many more out there. Jump is Z on a keyboard, Xbox is A, and Jump is X in <i>Spelunky 2.</i> Obviously, this multiplies
greater and further to many other platforms. The solution for this is
a relatively straightforward and simple API
in Unity's Input System that allows you to bind any input to any other input on your device
using Interactive Rebinding. Let's take the scenario of attack. In this scenario, this code, or the subset of this code or a variation of this code
is in the Warriors project. You can download it
and see how I've set it up. In this case, we have
an Action Map of Player Controls. We have an Attack action.
The Attack action is a button. When you push a button,
the character will attack and swing their sword. You want to rebind this
to different things. We have this API, which uses
an InputActionRebindingExtensions of RebindingOperation. StartInteractiveRebind,
that's just a custom method. This could be when you push
a button in the UI or you open up some kind of menu, you create a new rebind action. With this, you assign the InputAction,
in this case, this Attack. You perform
the Interactive Rebinding, and OnComplete, you'll then
trigger RebindCompleted. It will start the rebindOperation. When this code runs,
you'll listen out for your next input on your device. If you have
a PlayStation controller, and X is for attack,
it will listen out for if you say push R3 or L1
or any other type of input. Then once that operation
has been completed, you push another button, it will then
dispose of that rebindOperation. Then here, you can
then apply your changes. Obviously, when you change
your binding to something else, you want to say, "Hey, update
the UI to be a different icon," or say "rebind completed,"
or something like that. You take your Input Action,
and via code, you can then say get Input Action
and assign it to here. Kind of like how the Cinemachine
was taking that Look action and applying it
to the Cinemachine data there. This is basically doing
the same thing but just using it
in a different way. We have
this StartInteractiveRebind, but there's a couple of scenarios
you might run into. You can accidentally bind it
to things that you don't want to. Let's take
the scenario of an attack. You probably don't want attack to be
bound to a mouse position movement, which might happen
if you're rebinding. It's very easy for someone to grab
the mouse and move it around to pause music or to pause
the game or something. Then that will detect
that the mouse is the interactive device
that's moved, so every time you move your mouse,
your character is going to attack, which doesn't look great. Obviously, you don't want to bind
it to things like Start. Using WithControlsExcluding,
you could say don't rebind it to mouse position
and don't rebind it to Start because then it's going
to be very difficult for you to fix the rebind if you're trying to push Start
to pause the game, and then you're just going
to be attacking all the time. The same with "/p,"
which could be like pause, or "/escape,"
which is usually saved for exiting the game or pausing. There may be
some very specific controls you don't want
to rebind your action to. So hit with this, you can use
WithControlsExcluding. Here is an
OnMatchWaitForAnother (0.1f). It's kind of like waiting
for a little duration of time before it runs the OnComplete,
and then you can then apply it. You can use
the pretty standard Rebind code. It's very simple,
very straightforward. It's documented as well, so you can
look there for some more examples. But you can also use
some extra elements of the API to exclude some use cases
you might run into or some bugs you might run into. Let's switch over to the Warriors
system and see how this works. For this, I'm going to go
into Local Multiplayer mode. If I run around my keyboard,
and I push P, which switches from Action Map
Player Controls to Menu Controls, I can then come to this UI using
that Event System to control it. Here, we have
this simple rebind UI. Here, it's going to display the
binding name, in this case, Attack, which is this one here. Here is the current key,
which is E, to attack. We can inspect and see E is attack. Then I can click it. If I click that button,
it's then going to go to that custom method
StartInteractiveRebind. It's now listening out for rebind.
Okay, I can move the mouse. But I'm going to push
another key on my keyboard. Let's do Right Control. Then OnComplete updates the UI. Now, Right Control is active. So now, if I run around
and hit right control, obviously, you can't see it right now,
you just have to take my word for it, I can push right control,
and it's going to attack. Similarly, I can then open this up. Let's do something like Backspace. Obviously, it's such
a ridiculous scenario, but it's demonstrating that you can
set up this Interactive Rebinding using this very small bit of code
for different things. Maybe attack is L. Then use L for the attack. That's great on a keyboard,
but what about on a gamepad? I've picked up
the PlayStation controller. I'm going to pause the game
and go back to Rebind Controls. What you'll notice here
is currently it's bound to X. It's displaying a little icon. It's displaying that icon because
I've created a very simple tool, which takes in the binding, so you take the binding,
which is currently active, in this case, Button South
on the gamepad. It's then going to this tool. It then goes to a binding set. It basically says Button South
is this icon here, PS4_Cross, now display this icon. This isn't specific
to the Input System, other than taking bindings,
and assigning them here, but it's a tool you can extract
for your projects. But I'm using this here
to demonstrate how you could tap into data
from the Input System and then build a tool around this. If I now select
this button and hit X, it's now listening out
for another input on my controller. Let's do R2 and unpause the game. Now, if I press R2, you can probably hear me
moving the trigger, is then going to do an attack. It remembers that, and this is
applying it to the Player Input. So, if I find the Player Input
for the PlayStation controller, which is this one here, it's applying that rebind or
that override to that Player Input. So this being rebound to R2
is different to the keyboard that's being rebounds to L,
backspace, or whatever it was. You also have the beauty of being
able to bind to anything you want. I could bind this to the Share
button if I really wanted to, which doesn't make sense
in the grand scheme of an attack, or maybe even the touchpad,
so now, when I leave the game, the touchpad
is now being used to attack. Of course, something
a bit more traditional, which is R3 that can attack. Now, if I pick up
the Xbox controller, as that's a different Player Input
and different type of device, it's no longer X,
square, triangle, circle. Microsoft obviously uses
A, B, X, and Y. I can then change this
to, say, a Y to attack. Then the Y to attack
on this Xbox player. If I switch to the other one... I'm juggling
all these devices on my desk. That's obviously an A still because
it's overriding that Player Input, so each player can set up
their own control schemes, and their own input sets, and then it's going
to apply it to that Player Input. I'm using here 2019.4 LTS and Input System 1.0.0 package. I've heard that 1.1 package has an API to be able
to take these rebinds inputs and be able to export it to JSON. You'll be able to export it,
so when you leave the game or you want to share input maps,
you can then leave and reload it. This is not currently
in the Warriors project, but I'm looking into updating it
to make use of this API soon. I wanted to just let you know
that API is there if you use 1.1, and you'll be able
to make use of it using this Interactive Rebind API. Device disconnect/reconnect. This is kind of a strange scenario and where it's not
as interesting as Cinemachine or navigating UI on local
multiplayer things like this, but it's a needed thing
to fix or solve, especially if you're going
to make local multiplayer games. This is a scenario
where you have three players, and they all have their own gamepad,
and this could be wired or wireless. Then let's say Player 2 gamepad
becomes disconnected, and this could happen
through it runs out batteries, or it's unplugged,
or something like this happens, or it breaks. But then you reconnect it,
you go to the store, you buy new batteries,
or you replug it into your computer or games console,
and then you reconnect. You need to detect
that these events happen. When the disconnect happens,
you want to pause the game, throw up some UI, and say, "Hey, Player 2 is disconnected,
reconnect," and things like this. Obviously, when you reconnect,
you want to say, "Player 2 batteries
are now plugged in," something like this,
"Press A to continue," because you don't want Player 2
to be in a disadvantage in a racing game, a fighting game,
or something like that. So the way that you can detect
that this happens is through
the Player Input component. As I mentioned earlier on,
each player or each player in a local
multiplayer situation would have
a Player Input component. The Player Input would detect
when a disconnect happens but also when a controller
has been regained as well. This is through an API called
Device Lost and Device Regained. On the Player Input,
when you set up your Unity events or send message or your behavior, you can then assign an event here, so it's going to trigger
when Device Lost happens and when Device Regained
happens as well. It's just a method like this,
OnDeviceLost. In the Warriors project,
it actually updates the visuals, so the character
will have a gray beard, and it will say "disconnected,"
if I remember correctly. Then OnDeviceRegained, it's then
going to WaitForDeviceToBeRegained because, obviously,
when you plug in a controller, the OS has to detect
that it's plugged in, and it's a value controller,
it doesn't happen instantly. It happens after a second or two. Then once that regained
is finished, you can then unpause the UI
or do something. In the Warriors case,
it then recolors them to whatever the devices
that you've plugged it in. Now, I'll switch back to Unity
and make sure in Local Multiplayer. We've got here our characters. If I select one of them,
let's select the Xbox character. We've got one of the Xbox people. I think this one selected
is Player Three. You'll see we've got
Device Lost, Device Regained, and also Controls Change, so if we
switch from an Xbox controller to, say, a PlayStation controller. Obviously,
this would happen on a PC, not necessarily on an Xbox console. We have here OnDeviceLost, which would then go
to the code and say, "Display this new Device Lost UI." OnDeviceRegained
is then going to detect it again. If I now go to the Xbox controller, and I'm going to unplug it
from my computer. So I've now unplugged it. Did I unplug it? I unplugged the wrong thing.
One sec. Okay, I've unplugged
the right thing now. So I've unplugged
the Xbox controller. Obviously, the other warriors
are controllable, and I can run around with them. But you'll notice
that it says "disconnected," and the character's gone gray. It's displayed that UI above
the head, and I can't control it, but the game is still active,
and the game is still running, so if I now replug in
that Xbox controller, after a split second, it'll then
be detected and picked up. I can also do things like unplug
the PlayStation controller. So I unplug it,
and this should be a good way. Unplug the Xbox controller, and now, I can replug in
the PlayStation controller, and it's going to remember
that that was Player 2, so it's not going to override the
PlayStation to the Xbox controller. It's very smart in remembering what was disconnected
and what was regained. So something
that was quite troublesome or quite a bit of a headache
to sort out in the past with the Input Manager, it's actually pretty simple,
and it took me an hour or two to set up this whole Device Lost,
Device Regained system and make sure
it was all working great. I probably took less time
because the API is so automatic. You can now detect when these
things disconnect and regained and, obviously, in this scenario,
it just recolors the character, but you could throw up
a pause menu, you could say Player 4 is disconnected,
and things like that. That's the end of the presentation. I'd like to thank you
for watching this and tuning in. As a note, this project
was using 2019.4 LTS and the Input System package 1.0, which is verified for 2019 LTS and newer versions, like 2020.1,
2020.2 and things like that. The Input System package 1.1
is in preview for Unity 2019 LTS
and newer as well. That has more features
and functionality added on top
of what I showed you today. We have a lot more information
on this Input System landing page, such as links
to, eventually, this webinar, but then the previous
Input System webinar where we met with Renee and Will and spoke about different things,
different designs and functionality
of the Input System, plus a variety of other examples
and content on there. You can also download
this "Warriors" example project. Everything I showed you now
is in this GitHub repository, and it will be on Branch V2. The reason why I've set up
a different branch is for different snapshots
for this project. I created this project originally around the time of the first
Unite Now Input System webinar called Meet the Devs. I branched that off as V1 because if people
watch that webinar, they want to get
the project at that state, which is fine, but since then,
I've actually improved it, fixed bugs, added
extra functionality, tidied the code, made it
look a lot more optimized. For that, I've then
branched it as V2. You can download
this project webinar as a V2, which will basically be
as it is of this video. But if you download Master
or Main and on GitHub, you'll then get the newer version
with other bug fixes, so take note when you're
downloading this project of which version you're going
to be downloading from there. If I now switch over to GitHub, I can then show you that you've got
this project on GitHub. I've written some elements
of what it shows. Some parts you've already seen,
some parts you maybe haven't seen, maybe I haven't shown, and also some other features
it uses, like tone mapping, and nested UIs
for the input device. You're more than welcome
to take this project, learn from it,
extract code from it, build on top of it if, you want,
but I see it as a learning resource where people can dip into the code
and dip into different functions and say, "How do they display
the UI above the player's heads?" and things like that and be able to
extract it for your own projects. If you do that,
definitely contact me because I really enjoy seeing
how people use our example content and how we can improve it
for the future. My email is in this GitHub
repository in the readme here. Just to summarize, thank you for attending
this Unite Now webinar. I hope it was useful, and I hope it
will be helpful for your projects, whether you're going
to implement the input system or solving typical scenarios
in creating games. I hope to talk to you soon. Thank you. ♪ [MUSIC] ♪