Search Unity

Question Saving / Loading input actions with generated class

Discussion in 'Input System' started by zdolezal, Aug 5, 2021.

  1. zdolezal

    zdolezal

    Joined:
    Sep 27, 2017
    Posts:
    75
    So, I've created Input Actions asset which generated a nice C# class.
    But how to save/load the rebinds player did?

    upload_2021-8-5_16-50-54.png

    I see the generated class is using
    InputActionAsset.FromJson()
    itself. If there would be another generated constructor that I could call with my loaded
    InputActionAsset
    , it could work.

    Or how that's done properly?
     
  2. zdolezal

    zdolezal

    Joined:
    Sep 27, 2017
    Posts:
    75
    Hm it seems I even can't save
    InputActions.asset.toJson()
    as
    PerformInteractiveRebinding
    is not being saved there. That's strange - it's like the generated code is having it's own instance of the
    InputAction
    I want to modify?
     
  3. andrew_oc

    andrew_oc

    Unity Technologies

    Joined:
    Apr 16, 2021
    Posts:
    77
    Hi zdolezal. The way to save and load rebinds is through the SaveBindingOverridesAsJson and LoadBindingOverridesFromJson extension methods. There is a sample with the input system called RebindingUI that demonstrates these, saving to and loading from PlayerPrefs, but you can put the rebind json string where ever you prefer.
     
  4. zdolezal

    zdolezal

    Joined:
    Sep 27, 2017
    Posts:
    75
    Yeah, I saw RebindingUI but I can't get how to use these "rebinds" when using the auto-generated C# class from .inputasset

    I am on 1.0
     
  5. andrew_oc

    andrew_oc

    Unity Technologies

    Joined:
    Apr 16, 2021
    Posts:
    77
    You can use the 'asset' member from your @InputActions class, something like:
    Code (CSharp):
    1. @InputActions actions = new @InputActions();
    2. actions.asset.LoadBindingOverridesFromJson(...)
    Also there have been a lot of bug fixes around this stuff in the 1.1.0-pre... versions. Would recommend an upgrade if you can.
     
  6. zdolezal

    zdolezal

    Joined:
    Sep 27, 2017
    Posts:
    75
    Thank you andew for your reply, I'll try that and upgrade to beta then!
     
  7. zdolezal

    zdolezal

    Joined:
    Sep 27, 2017
    Posts:
    75
    The 2nd issue was that the generated class is having its own instances of
    InputAction
    s, probably.

    Because when you somehow use your example of RebindUI, the InputAction gets new rebind but it's not in the generated class.

    upload_2021-8-6_14-41-43.png

    There should be a way how to update the generated class InputActions with the update (rebinded) one. Then I could call also the
    InputActions.asset.SaveBindingOverridesAsJson()
    . You know, a way to update one InputAction in that generated class.

    Or is there other elegant way how to approach that (while still using the generated class in my events subscriptions, which I pretty like)?
     
    Last edited: Aug 6, 2021
  8. andrew_oc

    andrew_oc

    Unity Technologies

    Joined:
    Apr 16, 2021
    Posts:
    77
    Right, so in that case, where you're not using a direct reference to your input action asset, but creating a new instance of it at runtime, the Action on the RebindActionUI would have to also be set up dynamically, something like:
    Code (CSharp):
    1. @InputActions actions = new @InputActions();
    2. _timeZeroToggleRebindActionUI.actionReference = InputActionReference.Create(actions.GameControls.TimeZeroToggle);
    3.  
    and then everything will be pointing at the same instance of the asset. Hopefully I've understood what you want to do.
     
  9. zdolezal

    zdolezal

    Joined:
    Sep 27, 2017
    Posts:
    75
    Yeah, thank you. I have done it exactly that way :).
     
  10. zakirshikhli

    zakirshikhli

    Joined:
    Apr 8, 2016
    Posts:
    19
    Here is how to Load saved Overrides:

    "ControlCenter" is the name of InputActions asset file. Generate C# class was enabled.

    Code (CSharp):
    1. public ControlCenter controlCenter;
    2.  
    3. void Awake(){
    4.      controlCenter = new();
    5.      var rebinds = PlayerPrefs.GetString("rebinds");
    6.      if (!string.IsNullOrEmpty(rebinds))
    7.          controlCenter.LoadBindingOverridesFromJson(rebinds);
    8.      controlCenter.Enable();
    9. }
    10.  
    11.   void Update(){
    12.   if (controlCenter.Ingame.Fire.WasReleasedThisFrame()){
    13. //Do something
    14.   }
    15. }