Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Usage pattern from ECS Jobs

Discussion in 'Input System' started by siggigg, Mar 20, 2019.

  1. siggigg

    siggigg

    Joined:
    Apr 11, 2018
    Posts:
    247
    Hey,

    I've been playing around with the new input system and trying to use it from ECS/Jobs code.

    I managed to load the bindings file into a job and set up all the bindings using input action callbacks, but I feel that is a lot of unnecessary methods just to set variable I then pass into a job.

    Is there a way to poll for the status (started/cancelled) of actions instead of using the performed/started/cancelled events? I see from older examples that there used to be a field called "hasBeenPerformedThisFrame" but that seems to be gone now.

    This is an example of what I'm currently doing.

    Code (CSharp):
    1. protected override void OnCreateManager()
    2. {
    3.     base.OnCreateManager();
    4.      
    5.     InputActionAsset asset = Resources.Load<InputActionAsset>("GameInputBindings");
    6.     inputManager = new GameInputBindings(asset);
    7.     fireAction = inputManager.Gameplay.Fire;
    8.     fireAction.started += OnFireStarted;
    9.     fireAction.cancelled += OnFireCancelled;
    10.     fireAction.Enable();
    11. }
    12.  
    13. private void OnFireStarted(InputAction.CallbackContext context)
    14. {
    15.     IsFiring = true;
    16. }
    17.  
    I tried polling fireAction.phase and I could see it's being set to Started, but goes straight back to Waiting and never shows Cancelled or Performed.
     
    Ofx360 likes this.
  2. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    If you're fire action is tied to a Press button, there may be a bug where it Performs exactly once and then never again, unless you have the Continuous flag set to true: https://github.com/Unity-Technologies/InputSystem/issues/470. It's been reported by at least 1 other user in the main input system forum thread.

    As for your other issue. I wouldn't pull the actions into the manager directly.

    Instead write an ECS-Convertible Monobehaviour component that sets all that up and either caches the event state, or uses the InputActionTrace class to buffer the action results, and then use the System to pull the data out of that.

    That's what I've recently re-written my setup to do and it's pretty straightforward after you wrap your head around the conversion pipeline interfaces.
     
  3. siggigg

    siggigg

    Joined:
    Apr 11, 2018
    Posts:
    247
    Yeah I initially tried using the conversion pipeline to convert maps/actions set in a behaviour into components, but quickly ran into issues since none of these classes are blittable.

    I could do the polling in a MonoBehaviour but IMO that's not any better than polling from the job.

    What I currently do for Vector2 values is catch the started/cancelled events, save the CallbackContext instance and then call ReadValue<Vector2>() on that in my OnUpdate()

    I will look at the InputActionTrace class, thanks.
     
  4. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    You can add non-blittable classes to an entity via the conversion pipeline, and access them safely in ComponentSystem. Look at EntityManager.AddComponentObject() instead of EntityManager.AddComponentData(). You can also set the ConvertToEntity setting from Convert and Destroy to Convert and Inject GameObject, and that will retain all of the existing MonoBehaviour/Components on the converted GO, without you having to do any extra work in to re-add the Mono components.

    Right now I just use InputActionTrace + action maps and action GUIDs to filter and on the main thread into blittable event buffers, then do all my processing on JobComponentSystems.
     
  5. siggigg

    siggigg

    Joined:
    Apr 11, 2018
    Posts:
    247
    To clarify a bit, I'm not really confused about the nature of ECS here. And I already have a functioning prototype that allows me to use re-bindable input in my ECS project.

    I am unhappy about there only being an event-driven model to get the input data.

    I want to be able to do things like this:

    Code (CSharp):
    1. InputActionAsset asset = Resources.Load<InputActionAsset>("GameInputBindings");
    2. var gameplayActionMap = asset.GetActionMap("Gameplay");
    3. InputAction fireAction = gameplayActionMap.GetAction("Fire");
    4.  
    5. // This I cannot do atm, or at least I haven't found a way to
    6. var isFiring = fireAction.ReadValue<bool>();
    7.  
     
  6. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    InputActionTrace should give you something pretty close to that.

    Code (CSharp):
    1. // Set up.
    2. var myTrace = new InputActionTrace();
    3. myTrace.SubscribeToAll();
    4.  
    5. // Process during update.
    6. foreach (var action in myTrace)
    7. {
    8.     // Phase, value, etc. are all available from the action "event".
    9. }
    ////EDIT: Forgot that you'd also want to flush the trace at the end (myTrace.Clear()).
     
    Last edited: Mar 21, 2019
    siggigg likes this.
  7. Ofx360

    Ofx360

    Joined:
    Apr 30, 2013
    Posts:
    155
    When i was messing around with getting the input system into ecs, i had to make a dedicated system to process the inputs and then had a single entity with an input struct with all the necessary actions (Fire_Up, Down, Pressed, etc). The setup also gave me a nice place to handle bespoke actions like combos.

    Then i could just get the data for any of the systems that needs inputs rather than setting up awkward events all over for various system that needed inputs. I just need to setup awkward events and stuff in one place

    I REALLY hope that one day inputs from ActionMaps etc get way to just poll the inputs...please!
     
  8. Ofx360

    Ofx360

    Joined:
    Apr 30, 2013
    Posts:
    155
    I’ll check this out next time! Looks like it’ll make processing events much better for me
     
    siggigg likes this.
  9. siggigg

    siggigg

    Joined:
    Apr 11, 2018
    Posts:
    247
    Thanks! Going to give this a try :)


    That is the pattern I'm following, I just wasn't happy with how I was populating the input struct (component) in the system.
     
  10. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    I think eventually we'll have an API for that but my guess is that even then in most cases one may be better off with InputActionTrace. The polling-based API is probably going to drop some data and it will for sure aggregate data as any number of state changes may have happened in-between the last polling and the current. The advantage of InputActionTrace is that it sucks all the data into unmanaged memory and you can traverse the full trace step by step and do pretty much anything on top.

    InputActionTrace can also pretty straightforward be made thread-safe for reading by multiple consumers.

    There's still classes (like InputAction) involved so that's an obstacle of its own. That one remains to be solved as part of resolving input for ECS in a bigger scope.
     
    foxnne, NotaNaN, Ofx360 and 2 others like this.
  11. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    309
    So, a bit more than one year later, what are the recommended approaches to using the new input system and DOTS?
     
    onehundredfeet likes this.
  12. onehundredfeet

    onehundredfeet

    Joined:
    Oct 31, 2010
    Posts:
    15
    I would also like to know this. A white paper or blog post would be great. It seems like a bit of a hole right now. Most of the samples are pure simulation.
     
  13. Rene-Damm

    Rene-Damm

    Unity Technologies

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    ATM the recommended approach is to pick up input in OnUpdate as from other main-thread-constrained Unity APIs. Optionally, the system can be put into manual update mode and InputSystem.Update can be called right in OnUpdate before processing inputs.

    From there, input data can be routed into jobs. For the most part, this is equivalent to picking up input from UnityEngine.Input from OnUpdate methods.

    FWIW I did some prototyping recently for dedicated DOTS input support and expect that we're starting to slowly ramp up efforts here to get full support out.
     
    Mikael-H, thelebaron and optimise like this.