I also used extra layer of abstraction while setting up my input system, but never thought about diong it with SO. That is actually a game changer, deffinitely gonna improve my game with this idea, thanks!
@@KingRecycle69 I know this is old so maybe this has been answered for you already, but using an SO just means you don't need a game object to run the script and you have full control over when the script is loaded and unloaded from memory.
I think things finally just clicked for me on all this! I have struggled so much with perfecting a input system that uses all the robust features of the new input system and is simple to understand to implement across my controllers!! Thank you so much!!
Amazing video! I've been searching for a deeper understanding of a professional input setup and this was a perfect video illustrating the design concepts. I had encountered fragments of what was discussed here in various places like forums and other videos but the information was always incomplete or glossed over. You really put everything together completely.
This is incredible, Paridot. This fixed all the issues I was having with my movement and the handling of all the different states. This was invaluable.
This video was on my 2 weeks old tab designated to be watched some day... :) Finally watched it today, subbed, you have awesome teaching ability. And I was looking for the way to jump over to new input system, thanks.
I remember watching this when I first started with unity and had no idea why you did it this way and it seemed all so complicated and weird. I didn't know what events were or Scriptable Objects. I had watched so many other videos on the input system and in all of them people did it different (tutorial hell). I found an easy way and stuck with it for a while, because it worked. Now months later, while still being a noob, I totally get it and I really appreciate your way of handling inputs. it's easily the most methodical and cleanest way that I have come across and for me the only way to do it. The only "issue" that I see, and maybe you just forgot (or maybe I am still too much of a noob), is that you didn't unsubscribe from the events to prevent memory leaks. but yeah cheers for showing this!
I´ve found this just recently, but please. Let me pay you to teach me, the calm and good way you explain alone this. I´m sure you could explain much much more in a very great way. Thank you so much for this and many upcoming videos :D
I don’t know why i did not find your video when i was searching how to implement the input system with the generated C# class instead of the input component. I ended up with a messy player script because i don’t have the skill yet to create that intermediate layer, so i put everything in the player controller script. Looking forward to more content!
I've been using this exact system that I basically ripped off from the Chop Chop community project that Unity started a while back. It helped me a lot compared to instantiating different instances of the generated input class in different scripts.
Just earned a subscribe. I actually was starting to tackle this today, and was having issues with the jump. Move was a breeze. Just couldn't figure out the button part. awesome stuff!
I've always been using Unity's build-in solution and using the unity events methods to hook up my corresponding functions. It works indeed just fine, but Unity Events are more cost heavy then C# events. I'm glad I found this video showing me how to set this up similarly to Unity, but better! :) The fact that you've even turned it in to an SO made me really curious on how I could implement this solution in my own project. :) Thank you so much for making this video! It learned me something new! :D UPDATE: I've been tinkering with your method some more and I've managed to improve it a bit. :) Instead of making a function for each type of action map you want to use, I instead have one function that passes through the new action map name I want to enable. I loop over all the action maps and compare the names and if they match I'll enable the action map, otherwise I'll disable it. :) Here is the code I've used to make it more managable: public void SetActionMap(string newInputActionMap) { foreach (InputActionMap inputActionMap in _gameInput.asset.actionMaps) { if(inputActionMap.name == newInputActionMap) { inputActionMap.Enable(); } else { inputActionMap.Disable(); } } }
I'm happy you found it useful enough to expand on! That is a great improvement for handling which actionmap to have active. Nice and simple for whoever is calling the function and allows for many actionmaps without more code. Thanks for sharing!
@@paridotgames no problem! The only thing I couldn't improve upon was all the set callbacks functions you set in the on enable function for each individual action map. Unity generates there own structs for each individual action map so I can't store them in an array or list so I could loop over them as well and call the set callbacks function of each of them.
@@ZombiehuntersComeback this is probably necroposting, but here's how to further "improve" your approach. I put it in quotes because it has no real benefit other than your own satisfaction with the functioning of this improved option - Have the activa map cached in a different variable. Whenever you need to enable another map, disable the cached one, enable the passed map and cache it. No loops, comparison, O(1) and other useless stuff about optimisation attached
@@ZombiehuntersComeback Can't you just do some strategy pattern oriented design to handle the inputs? I made an abstraction to handle different input devices, so my InputManager doesn't need to know how handle different input types of fx the Movement input (It could be a Vector2, or axis and thus needs different handling). The behaviour just gets passed on to whichever device is currently active. I imagine something similar can be done with actionmaps
If anyone is having issues with the Debug.Log not showing anything (14:50), make sure "Reload Domain" is enabled under "Enter Play Mode Settings" in the project settings. I had it disabled and spent a long time trying to understand why it wasnt working
Make sure you dont bind the actions in the start() method like shown in the video. instead you should bind and unbind them in OnEnable() and OnDisable() to avoid null refs when respawning gameobjects like the player or scene changes. using OnEnable and OnDisable is also the way it was done in the example open source project but its missing in this tutorial.
When I saw multiple Action Maps being created (GamePlay and UI) and multiple actions (Move and Jump) and multiple controllers/bindings (WASD and GamePad), I realized there's going to be a lot more video watching and typing than necessary. DRY and KISS principles can apply to teaching videos. Just my 2 cents as someone with the attention span of a … oh got to go! Subscribed BTW.
Thank you so much, just found you and I really like your code style. Saved and will return further more to that video! But can you also recommend, please, which books did you read or where did you learn all of that?
Great to hear, thank you! Check out the end of the video, around 23:50 - I studied one of the Unity example projects and what I showed in the video is the basics of what I found in that project
@@paridotgames Yeah, there is one thing I noticed, that you need to recreate InputReader scriptable object in your asset folder, every time you adding some new movement, so it better to have everything planned as early. Overall thank you again brother, very good video.
I'm having trouble and hope someone can help. I followed the video step by step but encountered a problem in playmode. The first time i enter playmode after creating a new Input Manager Scriptable object everything works as intended, but as soon as I exit and reenter playmode (without deleting the existing Input Manager SO) none of my inputs are detected. Anyone run into this? Anyone solve it?
There's something about it being a ScriptableObject meaning that it only gets enabled on first play (or after reloading scripts). IDK if this is the best solution but if you make the OnEnable function public and then call it from another script derived from Monobehaviour in OnEnable it should fix it! Or at least it did for me after experiencing this identical issue.
That's a very nice implementation. Just one detail regarding your video: for a non-native English speaker, sometimes is hard to hear your voice. It's like you're speaking so low that your voice becomes hoarse, and it becomes difficult to understand.
Thank you for the feedback! I have to consciously remind myself to annunciate more with the low voice I have lol - I'll work on making future videos more clear!
I figured it out but now I got a new issue. I can't click buttons in the UI if action map is Player. I want to be able to click some UI without disabling player input. Like clicking a world space button or hovering over a UI element. The issue is that the Pointer can only be set to one thing. @@paridotgames
Pretty nice solution! This is the endless struggle of using Unity, you typically want to take advantage of its nice editor features (like its serialization) and in the same time to move away from its counter productive API. The new input system is pretty powerful but it is no easy task to properly abstract its functionality. Also, are you using Rider? How did you made it to look so lightweight? Congratulation again for the grate video!
It’s a cycle of getting really mad about an annoyance then being really excited about finding the solution lol. Glad you found it interesting! Also yes it is the newest release of Rider. In the appearance settings you can turn on the beta for their new interface - you’ll likely have to update your rider first. I’m really liking it so far!
That would not work with the way I'm doing it, although I'd imagine you could whip up another way of abstracting input with a static class. But in this case, if you want to map the input interface onto this class it has to be non-static to satisfy C# rules as well as to deal with the instance variables created here - it needs to be instantiated.
Unless you're talking about just making the events static (not the whole class), then you wouldn't have to have a live reference to the SO in other scripts - I didn't think about that, it would definitely work for single player game and reduce the need for manually assigning dependencies. In which case that's a great idea lol!
Great video! Two questions though, (1) how does this system deal with 2P? Does this same approach work when working with control schemes? (2) how does this work with AI input? I am wondering because AI Input does not have Input system actions. Do you write extra methods in the Input Reader, or does the AI Input replace both the Input System and Input Reader altogether?
My game input screen does not seem to have a "listen" button. nor can I seem to find the keyboard (space) key in the list? How can I use spacebar for a jump action, in this case?
disabling the UI action map doesn't actually prevent the EventSystem from using the actions defined in the InputSystemUIInputModel component though does it? Would you use Unity's provided Interfaces for UI with this setup?
Hello great video !! I fully understand everything and it was really nice, i have a question cause i already implement a input system but in my case i use a MonoBehavior, there is any difference between these two? more than one must be assign to the object and other is just there in the project ? Thank you!!
Thank you for watching! Both cases work, but it's slightly cleaner in this case to use a scriptable object since their is no transform required for the inputreader and input is usually persistent between scenes, which is a great use case for scriptable objects. It's extra work that's unnecessary if you use a MonoBehaviour.
It is because with Scriptable Object you can subscribe / unsubscribe actions to the same events across project, they are saved in this created SO file. With plain C# in GameManager and PlayerController you would have two different InputReader objects with two different GameInputs. Scriptable Objects helps with Observer pattern here.
hey very nice approach but i got a question is it viable or better in anyway to NOT use the unityEvents Actions and instead use public variables to store the values directly in the Scriptable object inputReader for example inside The OnMove(InputAction.CallbackContext context) method we can say MyVariable = context.ReadValue()) , and simply access MyVariable on the playerController code that is already referencing inputReader... is it less expensive than subscribing to events or am i missing something ? Thank you so much!
I think the main difference with doing `MyVariable = context.ReadValue()` and using events is that it means that in the playerController, you wont know when the player is actually moving, so you'll have to check for the value of MyVariable every frame probably, in the Update function, where as with events, you can only do work when the player is actually moving. You should not be worried about the performance of events for things like these, that's not where your game will struggle perf-wise.
@@niuage Yes after you are right to use variable it would need an update callback to check the value every frame and it would be redundant thank you very much
You mentioned UnityEvent Actions, but I am not using anything related to UnityEvents. Here I am using Action's which are just pre-defined delegates, which is an important distinction. If I were using Unity events, the performance cost would be much more important to consider. To answer your question though, in this specific case you're right in that the performance would be (minimally) better with public variables instead of events since in the controller, we are simply reading the move value in the update call anyways. Your suggestion would remove a step without any consequence, so this is a very good observation on your part. However in a more complex case this would probably reduce readability, and the performance hit for using events instead is an extremely small cost for keeping things organized
Thank you for your video, good editing as well. I'm a bit questioning the purpose of the InputReader layer to be honest. Except from the fact that you're not instantiating the Input class for each component and make it a drag and drop Scriptable Object, what is the purpose of Observing an event on the Input class just to expose another event on the InputReader without any globalized goal here? It seems to me that you added a Layer Input Reader because you didn't refactorize and didn't want to register the Input class directly. I could be wrong and there's a real advantage to this layer but I'm very curious to hear it 🤔
The advantage to me is primarily organization. I mentioned this example isn't a great representation of it being used at scale, but when you have a significant game being made that has player and interaction controls, UI controls, different states that all have different controls, it gets hard to manage everything. But if you have a standard protocol and central location for where and how input is being managed, it becomes a lot easier to expand and debug projects - both in the input reader and in the controllers as they now both have more focused roles. With that said, I've also been using it for smaller projects just because it makes more sense for me now that I've used it this way a couple times. It just seems so much cleaner with miniscule performance impact.
This is cool and all, but how is this easier than just using the Player Input? We'd still need to create the scriptable object input reader anyway. Isn't it the same as attaching the player input component to the thing we want to control?
How would you extend this so only some ui can block only part of the gameplay map (ie only movement)? Making another action map ie UI_WITH_ONLY_X_ENABLED , doesn't scale. Setting particular actions enable and disable becomes such a mess also. Adding to this gui buttons action blocking is also such a mess. I havent found yt video that would satify all scalable requirements. Everyone just focuses on basics ;/
The events have callbacks in the generated file already. Why not use those? Also, why are you using a scriptable object for the intermediary? Won't both be attached to the player, which is loaded every scene anyway? There doesn't seem to be state information we're passing between scenes. I'm confused about the point of all this.
Solution is good. But I can't understand for what we used Scriptable Object? As I understand we simply can use an usual MonoBehaviour script. Would be really grateful to get feedback Does this method suit to handle touchscreen elements like a button (to open inventory in game etc)?
You can definitely simply use a MonoBehaviour script, but ScriptableObject is better suited in this scenario since no transform is required - we only need to instantiate a scriptable once for the entire project, instead of setting up a new input object in each scene like you would with a MonoBehaviour. This method would work for any type of input you want in the new input system. Handling UI button clicks uses UnityEvents, and that's a different topic, but yes you can process touchscreen input using this method.
@@paridotgames I learnt out that the OnEnable method is only executed when the ScriptableObject is instantiated. So that, this method works only when I start my game first time in the editor, but second time it doesn't work. There is a large thread on Unity forum about that bug. Devs won't fix it as I understood. To solve this problem we can create Manager which instantiates SO, when we need, but it seem so ugly. Oh, probably I'll use usual MB script, because testing process with SO is almost impossible
15:28 'The first thing we have to do in unity is create the Input Reader asset'. There is no asset in my create menu. Game over. That's 2 hours of my life I won't get back.
Ok yea there's definitely a bug in Unity (at least Unity 6 LTS.) Not seeing that menu item may be an issue due to an error in the script, and that error will show up with absolutely no fault of the developer. Unity is just up and losing (without any saving or rebuilding) the UnityEngine.InputSystem. I literally was watching the video and watched my script go from working to broken with zero changes because Unity just up and lost this somehow.
why would you make your own "input reader" when it already has an event system built into it? That's really redundant. The whole point to the new input system is so you don't have to do this
Great question! It might seem redundant with the small example in the video, but the purpose is to keep the controllers that need to handle input cleaner in the end. With the context parameter that the event system gives us, as useful as it is, it makes the controllers using it harder to read. The goal with this is to handle all of the parsing of data in one middleware input reader so we don't have to muddy the controller with it, and let them do the job they're really intended to do by giving them exactly and only the information they need. It might be hard to see with a smaller example, but Unity has a fantastic larger scale example that has been open sourced. If you are genuinely interested in learning about why you might do input this way, I'd highly recommend checking it out: github.com/UnityTechnologies/open-project-1/blob/main/UOP1_Project/Assets/Scripts/Input/InputReader.cs
@@paridotgames yeah of course, and that's usually the answer for any sort of architecture discussion. I should have phrased what I was saying differently. I guess I should have asked: What do you think your audience is made up of? What's your goal audience? Because I would say that most people using unity are solo / small group devs with small projects that would never ever need to use this (and not just you, plenty of other unity related content all teach people with small scale projects concepts designed for large scale games). Any junior who needs to know this, will definitely be asking their seniors about it because it was likely already implemented, and reading through some stack overflow articles as opposed to watching a video.
I'm hoping to reach the audience of people who are trying to improve their understanding of these systems. You're right in the sense that it might not be *necessary* for smaller projects, but it still (imo) makes it cleaner and easier to work with. I am a small indie developer and even though my projects are small, I have been using this system for several projects now, and I know that after solidifying the concepts in this video I have improved my workflow for implementing input systems cleanly and quickly. I think anybody who's interested would benefit from at least learning about this system whether they're small or large developers. Do you feel mislead or frustrated in any way about this video? I think the title and thumbnail of the video also reflects the fact that I'm not just going to be showing the very basics of the input system, but I could be wrong here. I genuinely do like the feedback, so thank you for engaging. I hope to make better quality videos in the future.
@@paridotgames no worries, when I was starting out I definitely got frustrated with how much architecture and design pattern stuff was inundated on me, it wasn't until I went and started making projects and running into the problems that required those solutions that these systems actually became useful and smooth to learn.
Also to your point about juniors finding other ways to get this information, maybe they're not employed and don't have senior resources to ask, or watching a video is more engaging than reading an article (My small attention span often appreciates videos explaining topics over having to read closely through an article lol). I don't think there's harm in adding more ways for people to learn about these things :)
Using a prebuilt system 🤢✋🏻 Using a system you built using a premade system you copied 😎🤌🏼 Note: i did not watch the video yet, just a joke im sure theres plenty of reason to use this video to develop a deeper level of understanding and i appreciate that
Yes, this is the best video about using the new input system. Basically, everyone shows an example using the playerInput component.
I also used extra layer of abstraction while setting up my input system, but never thought about diong it with SO. That is actually a game changer, deffinitely gonna improve my game with this idea, thanks!
Is there a reason to use a SO though? Curious.
@@KingRecycle69 I know this is old so maybe this has been answered for you already, but using an SO just means you don't need a game object to run the script and you have full control over when the script is loaded and unloaded from memory.
I think things finally just clicked for me on all this! I have struggled so much with perfecting a input system that uses all the robust features of the new input system and is simple to understand to implement across my controllers!! Thank you so much!!
That’s how I felt when I figured this out as well! Glad I could help you get there :)
Amazing video! I've been searching for a deeper understanding of a professional input setup and this was a perfect video illustrating the design concepts. I had encountered fragments of what was discussed here in various places like forums and other videos but the information was always incomplete or glossed over. You really put everything together completely.
This is incredible, Paridot. This fixed all the issues I was having with my movement and the handling of all the different states. This was invaluable.
This video was on my 2 weeks old tab designated to be watched some day... :) Finally watched it today, subbed, you have awesome teaching ability. And I was looking for the way to jump over to new input system, thanks.
I'm glad it found its way back from the old tabs lol, and thank you for the kind words!
I remember watching this when I first started with unity and had no idea why you did it this way and it seemed all so complicated and weird. I didn't know what events were or Scriptable Objects. I had watched so many other videos on the input system and in all of them people did it different (tutorial hell). I found an easy way and stuck with it for a while, because it worked.
Now months later, while still being a noob, I totally get it and I really appreciate your way of handling inputs. it's easily the most methodical and cleanest way that I have come across and for me the only way to do it. The only "issue" that I see, and maybe you just forgot (or maybe I am still too much of a noob), is that you didn't unsubscribe from the events to prevent memory leaks. but yeah cheers for showing this!
I´ve found this just recently, but please. Let me pay you to teach me, the calm and good way you explain alone this. I´m sure you could explain much much more in a very great way. Thank you so much for this and many upcoming videos :D
This is pure gold, really appreciate the way you explained the topic and implementation.
Thank you! I'm glad it was helpful for you!
"And you need something else to procrastinate with even though what you have right now works just fine"... I feel personally attacked🙃
I felt heard. @Paridot gets it!
I just subscribed. I'm an impatient person, so I absolutely love the pace and depth of your presentation. Perfect for guys like me!
Wow. Just Wow! Amazing walkthrough with Input system and it's usage! Thanks for sharing, and merry Christmas to you and your UA-cam channel!
Amazing guide man, you should have a tip jar or something, wouldnt mind giving 5 bucks for such good knowledge my man
It is scary... somehow it exactly answers my needs, and what I was searching for for several days. What can I say? Subscribed. Thank you!
I don’t know why i did not find your video when i was searching how to implement the input system with the generated C# class instead of the input component.
I ended up with a messy player script because i don’t have the skill yet to create that intermediate layer, so i put everything in the player controller script.
Looking forward to more content!
Thank you for letting me know! I added some tags so hopefully it reaches those searches better in the future.
Thank you very much for the video, this is the first time I've seen such an implementation and it's the best one I've ever seen
Glad it was helpful!
Perfect. Thank you. I was doing something similar with the "old" system so had the abstractions. Glad I found this before I tore it all down :)
That was the smoothest like and subscribe call to action 😂. Great tutorial!
I've been using this exact system that I basically ripped off from the Chop Chop community project that Unity started a while back. It helped me a lot compared to instantiating different instances of the generated input class in different scripts.
Yes Chop Chop has been such a fantastic resource! Glad to hear other people are also getting a lot from it
Just earned a subscribe. I actually was starting to tackle this today, and was having issues with the jump. Move was a breeze. Just couldn't figure out the button part. awesome stuff!
Thanks for subscribing! I'm glad the video was helpful for you :)
"This button isn't working for me for some reason, maybe you can... check it out see if it works for you" Hahaha, definitely subscribing after that.
I've always been using Unity's build-in solution and using the unity events methods to hook up my corresponding functions. It works indeed just fine, but Unity Events are more cost heavy then C# events. I'm glad I found this video showing me how to set this up similarly to Unity, but better! :) The fact that you've even turned it in to an SO made me really curious on how I could implement this solution in my own project. :) Thank you so much for making this video! It learned me something new! :D
UPDATE:
I've been tinkering with your method some more and I've managed to improve it a bit. :) Instead of making a function for each type of action map you want to use, I instead have one function that passes through the new action map name I want to enable. I loop over all the action maps and compare the names and if they match I'll enable the action map, otherwise I'll disable it. :) Here is the code I've used to make it more managable:
public void SetActionMap(string newInputActionMap)
{
foreach (InputActionMap inputActionMap in _gameInput.asset.actionMaps)
{
if(inputActionMap.name == newInputActionMap)
{
inputActionMap.Enable();
}
else
{
inputActionMap.Disable();
}
}
}
I'm happy you found it useful enough to expand on! That is a great improvement for handling which actionmap to have active. Nice and simple for whoever is calling the function and allows for many actionmaps without more code. Thanks for sharing!
@@paridotgames no problem! The only thing I couldn't improve upon was all the set callbacks functions you set in the on enable function for each individual action map. Unity generates there own structs for each individual action map so I can't store them in an array or list so I could loop over them as well and call the set callbacks function of each of them.
@@ZombiehuntersComeback this is probably necroposting, but here's how to further "improve" your approach. I put it in quotes because it has no real benefit other than your own satisfaction with the functioning of this improved option
- Have the activa map cached in a different variable. Whenever you need to enable another map, disable the cached one, enable the passed map and cache it. No loops, comparison, O(1) and other useless stuff about optimisation attached
@@ZombiehuntersComeback
Can't you just do some strategy pattern oriented design to handle the inputs? I made an abstraction to handle different input devices, so my InputManager doesn't need to know how handle different input types of fx the Movement input (It could be a Vector2, or axis and thus needs different handling). The behaviour just gets passed on to whichever device is currently active.
I imagine something similar can be done with actionmaps
This channel is a hidden gem!
I'm very happy you think so! Hoping it only gets better
Since you made me laugh within the first 30 seconds of the video, I am now subscribed. Thanks for that!
Wow, very good tutorial, I liked and subscribed
Thank you, this clarified a couple things for me
If anyone is having issues with the Debug.Log not showing anything (14:50), make sure "Reload Domain" is enabled under "Enter Play Mode Settings" in the project settings. I had it disabled and spent a long time trying to understand why it wasnt working
What a great guide, it was my first time with the new input system and it works perfectly. Thx !!
Let smash the subscribe button 👌
Clean Implementation - nice work !
This is great. Thanks for making this. So many tutorials just use the Player Input script and nice to see a better way.
Make sure you dont bind the actions in the start() method like shown in the video. instead you should bind and unbind them in OnEnable() and OnDisable() to avoid null refs when respawning gameobjects like the player or scene changes. using OnEnable and OnDisable is also the way it was done in the example open source project but its missing in this tutorial.
Correct, I sped through binding the events and it could have been done more carefully in the video. Thanks for pointing this out!
When I saw multiple Action Maps being created (GamePlay and UI) and multiple actions (Move and Jump) and multiple controllers/bindings (WASD and GamePad), I realized there's going to be a lot more video watching and typing than necessary. DRY and KISS principles can apply to teaching videos. Just my 2 cents as someone with the attention span of a … oh got to go! Subscribed BTW.
Thank you so much, just found you and I really like your code style. Saved and will return further more to that video! But can you also recommend, please, which books did you read or where did you learn all of that?
Great to hear, thank you! Check out the end of the video, around 23:50 - I studied one of the Unity example projects and what I showed in the video is the basics of what I found in that project
@@paridotgames Yeah, there is one thing I noticed, that you need to recreate InputReader scriptable object in your asset folder, every time you adding some new movement, so it better to have everything planned as early. Overall thank you again brother, very good video.
very insightful video!
This has everything I need, So glad find this video!!!!
This is treasure.
I'm having trouble and hope someone can help. I followed the video step by step but encountered a problem in playmode. The first time i enter playmode after creating a new Input Manager Scriptable object everything works as intended, but as soon as I exit and reenter playmode (without deleting the existing Input Manager SO) none of my inputs are detected. Anyone run into this? Anyone solve it?
There's something about it being a ScriptableObject meaning that it only gets enabled on first play (or after reloading scripts). IDK if this is the best solution but if you make the OnEnable function public and then call it from another script derived from Monobehaviour in OnEnable it should fix it! Or at least it did for me after experiencing this identical issue.
I had this same issue, enabling "Reload Domain" in the project settings seems to have fixed it
That's a very nice implementation. Just one detail regarding your video: for a non-native English speaker, sometimes is hard to hear your voice. It's like you're speaking so low that your voice becomes hoarse, and it becomes difficult to understand.
like in 8:58
Thank you for the feedback! I have to consciously remind myself to annunciate more with the low voice I have lol - I'll work on making future videos more clear!
love this
I dont get how to use th einput system for Aiming with a mouse or joystick. To shoot that direction in a 2d game. Anyone know?
I haven't used mouse input much in the new input system yet, but I'll see if I can figure it out and make a quick video on it. Stay tuned!
I figured it out but now I got a new issue. I can't click buttons in the UI if action map is Player. I want to be able to click some UI without disabling player input. Like clicking a world space button or hovering over a UI element. The issue is that the Pointer can only be set to one thing. @@paridotgames
Thanks for video. What is the best way to handle inputs in mobile projects?
Great video. Lean code. Thank you!
Pretty nice solution! This is the endless struggle of using Unity, you typically want to take advantage of its nice editor features (like its serialization) and in the same time to move away from its counter productive API. The new input system is pretty powerful but it is no easy task to properly abstract its functionality.
Also, are you using Rider? How did you made it to look so lightweight?
Congratulation again for the grate video!
It’s a cycle of getting really mad about an annoyance then being really excited about finding the solution lol. Glad you found it interesting!
Also yes it is the newest release of Rider. In the appearance settings you can turn on the beta for their new interface - you’ll likely have to update your rider first. I’m really liking it so far!
Amazing vidéo 🤙🤙
Still working on how to rebind sticks on gamepads so that you can switch sticks or use the dpad.
What is the name of the website that you're using for the input system visualization?
Figma
I think for the events, there can be created a static class. It would eliminate the necessity of creating the reference for the SO?
That would not work with the way I'm doing it, although I'd imagine you could whip up another way of abstracting input with a static class. But in this case, if you want to map the input interface onto this class it has to be non-static to satisfy C# rules as well as to deal with the instance variables created here - it needs to be instantiated.
Unless you're talking about just making the events static (not the whole class), then you wouldn't have to have a live reference to the SO in other scripts - I didn't think about that, it would definitely work for single player game and reduce the need for manually assigning dependencies. In which case that's a great idea lol!
Great video! Two questions though, (1) how does this system deal with 2P? Does this same approach work when working with control schemes? (2) how does this work with AI input? I am wondering because AI Input does not have Input system actions. Do you write extra methods in the Input Reader, or does the AI Input replace both the Input System and Input Reader altogether?
Might I suggest the events be static to remove the dependency on the scriptableobject being injected into every component?
aaand with THIS video you got my subscriiption.... HOOW does´t anyone mentioned this interfaces before??
How would you implement input rebinding ?
My game input screen does not seem to have a "listen" button. nor can I seem to find the keyboard (space) key in the list? How can I use spacebar for a jump action, in this case?
seems to be a unity bug. If you look closely above the box there seems to be a blue outlined search box, next to that is the listen button.
This is a decent tutorial but i'm stuck @ 11:33 because i'm having a namespace error/reference error how can i fix this?
disabling the UI action map doesn't actually prevent the EventSystem from using the actions defined in the InputSystemUIInputModel component though does it? Would you use Unity's provided Interfaces for UI with this setup?
11:16 What do you use? Radory? Readoi? I dont get it
the joyatick never go to zero what can i do?
Did you do something with the SO? After I made it and ran the scene, nothing happened. Edit: during the debug.log phase
Hello great video !! I fully understand everything and it was really nice, i have a question cause i already implement a input system but in my case i use a MonoBehavior, there is any difference between these two? more than one must be assign to the object and other is just there in the project ? Thank you!!
Thank you for watching! Both cases work, but it's slightly cleaner in this case to use a scriptable object since their is no transform required for the inputreader and input is usually persistent between scenes, which is a great use case for scriptable objects. It's extra work that's unnecessary if you use a MonoBehaviour.
@@paridotgames You rock buddy! Thank you so much!!
What is code editor?
Ohh, its rider new interface
Great tutorial! I have one question, why are you using ScriptableObject on the Input Reader and not just a plain C# Class?
It is because with Scriptable Object you can subscribe / unsubscribe actions to the same events across project, they are saved in this created SO file. With plain C# in GameManager and PlayerController you would have two different InputReader objects with two different GameInputs. Scriptable Objects helps with Observer pattern here.
great vieo
hey very nice approach but i got a question is it viable or better in anyway to NOT use the unityEvents Actions and instead use public variables to store the values directly in the Scriptable object inputReader for example inside The OnMove(InputAction.CallbackContext context) method we can say MyVariable = context.ReadValue()) , and simply access MyVariable on the playerController code that is already referencing inputReader... is it less expensive than subscribing to events or am i missing something ?
Thank you so much!
I think the main difference with doing `MyVariable = context.ReadValue()` and using events is that it means that in the playerController, you wont know when the player is actually moving, so you'll have to check for the value of MyVariable every frame probably, in the Update function, where as with events, you can only do work when the player is actually moving.
You should not be worried about the performance of events for things like these, that's not where your game will struggle perf-wise.
@@niuage Yes after you are right to use variable it would need an update callback to check the value every frame and it would be redundant thank you very much
You mentioned UnityEvent Actions, but I am not using anything related to UnityEvents. Here I am using Action's which are just pre-defined delegates, which is an important distinction. If I were using Unity events, the performance cost would be much more important to consider.
To answer your question though, in this specific case you're right in that the performance would be (minimally) better with public variables instead of events since in the controller, we are simply reading the move value in the update call anyways. Your suggestion would remove a step without any consequence, so this is a very good observation on your part.
However in a more complex case this would probably reduce readability, and the performance hit for using events instead is an extremely small cost for keeping things organized
Hello ! Good job for the video ! What is the name of the software to make the diagram please ?
Thank you! The diagrams were made in Figma
can you elaborate on why you use a scriptable object instead of anyhing else?
i mean having a static instance of the input reader class should do the job just fine right?
Thank you for your video, good editing as well. I'm a bit questioning the purpose of the InputReader layer to be honest. Except from the fact that you're not instantiating the Input class for each component and make it a drag and drop Scriptable Object, what is the purpose of Observing an event on the Input class just to expose another event on the InputReader without any globalized goal here?
It seems to me that you added a Layer Input Reader because you didn't refactorize and didn't want to register the Input class directly.
I could be wrong and there's a real advantage to this layer but I'm very curious to hear it 🤔
The advantage to me is primarily organization. I mentioned this example isn't a great representation of it being used at scale, but when you have a significant game being made that has player and interaction controls, UI controls, different states that all have different controls, it gets hard to manage everything. But if you have a standard protocol and central location for where and how input is being managed, it becomes a lot easier to expand and debug projects - both in the input reader and in the controllers as they now both have more focused roles.
With that said, I've also been using it for smaller projects just because it makes more sense for me now that I've used it this way a couple times. It just seems so much cleaner with miniscule performance impact.
This is cool and all, but how is this easier than just using the Player Input? We'd still need to create the scriptable object input reader anyway. Isn't it the same as attaching the player input component to the thing we want to control?
How would you extend this so only some ui can block only part of the gameplay map (ie only movement)? Making another action map ie UI_WITH_ONLY_X_ENABLED , doesn't scale. Setting particular actions enable and disable becomes such a mess also. Adding to this gui buttons action blocking is also such a mess. I havent found yt video that would satify all scalable requirements. Everyone just focuses on basics ;/
The events have callbacks in the generated file already. Why not use those? Also, why are you using a scriptable object for the intermediary? Won't both be attached to the player, which is loaded every scene anyway? There doesn't seem to be state information we're passing between scenes. I'm confused about the point of all this.
Solution is good. But I can't understand for what we used Scriptable Object? As I understand we simply can use an usual MonoBehaviour script. Would be really grateful to get feedback
Does this method suit to handle touchscreen elements like a button (to open inventory in game etc)?
You can definitely simply use a MonoBehaviour script, but ScriptableObject is better suited in this scenario since no transform is required - we only need to instantiate a scriptable once for the entire project, instead of setting up a new input object in each scene like you would with a MonoBehaviour.
This method would work for any type of input you want in the new input system. Handling UI button clicks uses UnityEvents, and that's a different topic, but yes you can process touchscreen input using this method.
@@paridotgames Thank you for such a comprehensive answer! Now I understand the difference, I will use ScriptableObject
@@paridotgames I learnt out that the OnEnable method is only executed when the ScriptableObject is instantiated. So that, this method works only when I start my game first time in the editor, but second time it doesn't work. There is a large thread on Unity forum about that bug. Devs won't fix it as I understood.
To solve this problem we can create Manager which instantiates SO, when we need, but it seem so ugly. Oh, probably I'll use usual MB script, because testing process with SO is almost impossible
I've always wanted to be a pro
Now’s your chance
15:28 'The first thing we have to do in unity is create the Input Reader asset'. There is no asset in my create menu. Game over. That's 2 hours of my life I won't get back.
You likely missed the “CreateAssetMenu” tag at the top of the scriptable object class - 10:40 in the video
poor bozo
Same here. The create asset menu tag is there but nothing shows up :/
Ok yea there's definitely a bug in Unity (at least Unity 6 LTS.) Not seeing that menu item may be an issue due to an error in the script, and that error will show up with absolutely no fault of the developer. Unity is just up and losing (without any saving or rebuilding) the UnityEngine.InputSystem. I literally was watching the video and watched my script go from working to broken with zero changes because Unity just up and lost this somehow.
why would you make your own "input reader" when it already has an event system built into it? That's really redundant. The whole point to the new input system is so you don't have to do this
Great question! It might seem redundant with the small example in the video, but the purpose is to keep the controllers that need to handle input cleaner in the end. With the context parameter that the event system gives us, as useful as it is, it makes the controllers using it harder to read. The goal with this is to handle all of the parsing of data in one middleware input reader so we don't have to muddy the controller with it, and let them do the job they're really intended to do by giving them exactly and only the information they need.
It might be hard to see with a smaller example, but Unity has a fantastic larger scale example that has been open sourced. If you are genuinely interested in learning about why you might do input this way, I'd highly recommend checking it out: github.com/UnityTechnologies/open-project-1/blob/main/UOP1_Project/Assets/Scripts/Input/InputReader.cs
@@paridotgames yeah of course, and that's usually the answer for any sort of architecture discussion. I should have phrased what I was saying differently. I guess I should have asked: What do you think your audience is made up of? What's your goal audience? Because I would say that most people using unity are solo / small group devs with small projects that would never ever need to use this (and not just you, plenty of other unity related content all teach people with small scale projects concepts designed for large scale games). Any junior who needs to know this, will definitely be asking their seniors about it because it was likely already implemented, and reading through some stack overflow articles as opposed to watching a video.
I'm hoping to reach the audience of people who are trying to improve their understanding of these systems. You're right in the sense that it might not be *necessary* for smaller projects, but it still (imo) makes it cleaner and easier to work with. I am a small indie developer and even though my projects are small, I have been using this system for several projects now, and I know that after solidifying the concepts in this video I have improved my workflow for implementing input systems cleanly and quickly. I think anybody who's interested would benefit from at least learning about this system whether they're small or large developers.
Do you feel mislead or frustrated in any way about this video? I think the title and thumbnail of the video also reflects the fact that I'm not just going to be showing the very basics of the input system, but I could be wrong here. I genuinely do like the feedback, so thank you for engaging. I hope to make better quality videos in the future.
@@paridotgames no worries, when I was starting out I definitely got frustrated with how much architecture and design pattern stuff was inundated on me, it wasn't until I went and started making projects and running into the problems that required those solutions that these systems actually became useful and smooth to learn.
Also to your point about juniors finding other ways to get this information, maybe they're not employed and don't have senior resources to ask, or watching a video is more engaging than reading an article (My small attention span often appreciates videos explaining topics over having to read closely through an article lol). I don't think there's harm in adding more ways for people to learn about these things :)
Using a prebuilt system 🤢✋🏻
Using a system you built using a premade system you copied 😎🤌🏼
Note: i did not watch the video yet, just a joke im sure theres plenty of reason to use this video to develop a deeper level of understanding and i appreciate that
lol there's never architecture that can't be improved ;)