The idea is to have a value that is updated in the action events, then in Update/FixedUpdate to use those values.
It actually mentions how to poll an InputAction in the seven ways to respond to actions link you posted.
Once you have the all the InputActions setup you only need to reference them and then poll them in Update/FixedUpdate.
@Chris-Trueman You mean you’re supposed to handle the input events by turning on flags and such so that in the next Update() you can handle the inputs? I didn’t come across that suggestion in the documents, but that could make sense. Can you maybe link me to it if you still know where it is?
The way you can poll actions involves having local references to all of your actions, which I don’t need when using the UnityEvents from the Player Input component. Maybe that C# script you can generate from the Input Actions asset helps with that, but I couldn’t find much documentation on how that script can be used.
You don’t actually need to cache values in the events so my initial statement is not entirely true.
By default the system is updated in the render loop. The Input settings shows Dynamic Update, which actually means sync’d to the frame rate. So you can use the values directly with out any worry of doing more input process per frame than necessary.
If you are using it with FixedUpdate then caching the values or setting it to process events in FixedUpdate would be the way to go. I use the default and cache input values that I use to modify any physics such as RigidBody.MovePosition(transform.position * inputValue * Time.fixedDeltaTime); seeing as that method will only process the last value that was passed in when FixedUpdate happens.
Not really something they put into the docs. I’ve been using that for Update/FixedUpdate Input syncing with the old system. The old system didn’t work well when you polled it in FixedUpdate.
I’ve tried it three different ways.
PlayerInput component which is the easiest as the component handles a few things for you like local multiplayer and input scheme switching with single player.
Using the class generated on its own and register the events in a script.
MyInput myInput;//This is the Input asset class it generates. Will be named what you named it.
void OnEnable()
{
if (myInput == null)
{
myInput= new MyInput();
}
myInput.MyActionMap.Enable();
}
void OnDisable()
{
myInput.MyActionMap.Disable();
}
void Awake()
{
myInput.MyActionMap.MyAction.performed += MyActionPerformed;
}
void MyActionPerformed(InputAction.CallbackContext context)
{
//Respond to action here
}
Lastly, I have used the Interface that it creates with each action map. It forces you to setup all the input actions for that action map. I don’t like this one, every time you add a new action you need to create a corresponding method for that action in that class, which can be a good thing or a bad thing. It also requires you to use the Input asset class it creates much like the above only a little easier to set the callbacks as you would do this in one call.
public class Player : MonoBehaviour, MyInput.IMyActionMap
{
MyInput myInput;
void OnEnable()
{
if (myInput == null)
{
myInput = new MyInput();
myInput.MyActionMap.SetCallBacks(this);
}
myInput.MyActionMap.Enable();
}
}
This works like PlayerInput though in that it sends all phases of input. The second option is capable of registering for each phase of the input cycle, giving you more fine grained use.
In the end I stuck with PlayerInput because of the scheme switching, so I can display the correct button actions on the screen for keyboard/mouse or gamepad.
@Chris-Trueman but if I’m doing a Transform.Rotate() on the camera for every mouse move event I’m doing ~8 rotations per frame, as I checked in the inspector. If I checked the mouse delta inside Update() I would only be rotating the camera once.
This leads me to believe it’s not as efficient. It’s probably equivalent to calling Transform.Rotate() ~8 times inside Update().
I’m not sure what this means, the wording is not super clear. They say:
“The Input System processes events at irregular intervals determined by the current framerate.”
But it doesn’t say how the event processing relates to the framerate. Do they poll for input events 10 times per frame? Once (not the case from what I’ve tested so far)?
For now I’m inclined to attaching the input action asset to my input handler script and using InputActionAsset.FindAction() inside Update() to poll actions like “Look around” or “Move” once per frame.
This method is not something I found explained in the manual anywhere though - the only polling example I remember seeing is Keyboard.current.space.wasPressedThisFramehere.
This page does describe polling as a way of dealing with events (“You can poll the current state of an Action whenever you need it; to do this, use InputAction.ReadValue<>()”) but it doesn’t say anything about how to get a reference to the InputAction objects.
I think the manual should not focus on listening for events if that is not as efficient as polling inside Update(). And to describe polling, it should point out the InputActionAsset.FindAction() method.
I’m saddened by the lack of clarity in the documentation. It doesn’t feel like the person writing it tries to put themselves in the headspace of someone who is completely new to the system.
My biggest gripe with it is that information on the same topics is spread around the manual and the scripting API reference. There’s even a “reference” section in the manual. You guys should really have a single source of truth for each part of the system. I find myself checking the manual and then finding the same information on the API docs written in a slightly different way, sometimes including random additional details that make a difference when it comes to understanding what’s going on.
Still, it’s better than the current UI Toolkit documentation :p:p:p
I just tested this myself, the faster the mouse moves the more it triggers the event. I get an average of 2 for my current game, but it is up to 8 that I can see.
Yes it doesn’t make any sense and is not clear enough. After testing all the update setting it appears that no matter what I do I cannot get it to only trigger once per frame, even calling InputSystem.Update() manually. I am also testing which phase the event is in as per this post and it is triggering the performed event multiple times per frame.
This leads me to conclude that my original statement still holds true, cache the value and use it in Update instead. Setting a Vector2 or a float 8 times per frame is trivial.
For the record, with profiling my player script update takes 0.00ms as well as the InputSystem event processing taking 0.00ms.
Maybe @Rene-Damm can clarify more on this and tell us why it would trigger 8 times per frame.
The first bit of code I posted is how you get that reference using the created class that matches the name of the InputActionAsset you created. It creates properties for each ActionMap that has properties for each InputAction that you can reference for convenience. PlayerInput is a wrapper around doing that, only it doesn’t need it to be a class and uses the InputActionAsset directly. You only need the class if you are not using PlayerInput.
This is completely subjective. It’s entirely dependent on the type of project. Some projects will be looking for every possible avenue to reduce frame time like VR, which will still need responsive input. Others will not care and just want it simplified because it does really matter. Unity will focus on the simple, while allowing for more customization/optimization for those searching for it. After all VR or high end graphics are not a beginner thing.
I agree it is lacking and difficult to find what you are looking for. That being said the system is not as hard to figure out for someone with more advanced skills or experience. In my 16+ years of programming experience this system is a god send compared to the old one. More like what Unreal has, not to compare really just that its more modern and modern programmers should be better educated or more experienced. Novice programmers/developers tend to create badly programmed games, and if Unity focuses on ease of use(artist focused) maybe that can change. Until then the programmers have to take up the slack.
I whole heartedly agree with you there. It isn’t a verified package though, so there is that. Then again the InputSystem is and the docs need a bit of a makeover.
Indeed at the moment the documentation is not very clear on how the generated C# wrapper compares to the Player Input component. You have to spend days studying the system to start getting an idea of the bigger picture. It’s definitely not obvious to a newcomer that you should do only one of either generating the C# script or using the Player Input component.
In my opinion they should pick one solution and stick with it, or make it very clear in the manual what are the pros and cons of each approach. At the moment none of these are true!
The new input system seems pretty well designed even though some of its workings are a little quirky (see my recent thread about how the “expected control type” field is confusing). The problem is it doesn’t matter how elegant and well designed your system is if the documentation makes it hard to penetrate.
There should be someone in charge of making sure the team’s work is not going to waste because 90% of people cannot begin to understand what’s going on
I guess some people are content with things just working, and can move fast by trial and error without having to form a clear image of the system they’re interacting with in their heads. I personally cannot move on without first understanding clearly what my options are and what the implications for each is, and it’s hard to be that kind of person and interacting with this system right now
I am not using PlayerInput. Instead I have references to InputActionReferences on my control script. Those can be assigned in the Inspector. Each one is a sub-item of the InputActionSet asset in the project panel.
Then on Start, from each InputActionReference, grab the InputAction via .action field.
Once you have the InputAction you can ReadValue it inside Update.
This feels pretty clean to me. Better than a bunch of string literals in code pulling InputActions out of the InputActionSet asset. Feedback appreciated.