Search Unity

How to maping an action with float value like 'move' with keyboard?

Discussion in 'Input System' started by watsonsong, Jun 25, 2018.

  1. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    I am listen the performed event and get value from the context to get the movement of our character.
    I want to bind this action with keyboard, such like a for left and d for right. But I don't known where to set it in ActionMaps.
    Is there any one can help me, for the new input system is really leak of documents.
     
  2. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    ATM there's no support for doing this in the UI. We're in the processing of redesigning and rewriting the editor UIs from scratch for setting up action maps and the new UI will cover setting up these kind of bindings.

    Right now, it can only be done either directly in code (there's an example here) and by manually hacking the JSON .inputactions file. Example:

    Code (JavaScript):
    1. {
    2.   "actions": [
    3.     {
    4.       "name": "gameplay/move",
    5.       "bindings": [
    6.         {
    7.           "path": "ButtonVector",
    8.           "isComposite" : true
    9.         },
    10.         {
    11.           "name": "Left",
    12.           "path": "<Keyboard>/a",
    13.           "isPartOfComposite": true
    14.         },
    15.         {
    16.           "name": "Right",
    17.           "path": "<Keyboard>/d",
    18.           "isPartOfComposite": true
    19.         },
    20.         {
    21.           "name": "Down",
    22.           "path": "<Keyboard>/s",
    23.           "isPartOfComposite": true
    24.         },
    25.         {
    26.           "name": "Up",
    27.           "path": "<Keyboard>/w",
    28.           "isPartOfComposite": true
    29.         }
    30.       ]
    31.     }
    32.   ]
    33. }
    And yeah, documentation is really lacking. Sorry for that. ATM things are still so much in flux that we're holding off on that a little. But it should hopefully improve soon.
     
    FROS7 likes this.
  3. GilbertoBitt

    GilbertoBitt

    Joined:
    May 27, 2013
    Posts:
    111
    I wanted the same thing. but i notice that the dpad keep getting something like 0,7... on diagonal. and i want to create the same way has dpad but like the old input system where i can get a vertical and horizontal axis to return a vector2 where x = horizontal axis and y = vertical axis. so for that i made a new composite base on the others i modified and add to registry here what i did and my example code. there 2 only downside to it. 1 is only possible via code or like he just show us above via hacking json and on my version i already have add invert boolean to when player want to invert it. but i just need create the code/serialization to add this like and appendSetBool or something similar.
    Code (CSharp):
    1. using UnityEngine.Experimental.Input.Controls;
    2.  
    3. namespace UnityEngine.Experimental.Input.Composites
    4. {
    5.    /// <summary>
    6.    /// A Double axis value computed from a "negative_x" and a "positive_y" button and
    7.    /// other from "negative_y" and a "positive_y"
    8.    /// </summary>
    9.    /// <remarks>
    10.    /// This composite allows to arrange any arbitrary 4 buttons to react like a sticky vector2 axis;
    11.    /// </remarks>
    12.    public class AxisStickComposite : IInputBindingComposite<Vector2>
    13.    {
    14.       // Controls.
    15.       public ButtonControl VerticalPositive;
    16.       public ButtonControl VerticalNegative;
    17.       public ButtonControl HorizontalNegative;
    18.       public ButtonControl HorizontalPositive;
    19.       public bool InvertVerticalAxis = false;
    20.       public bool InvertHorizontalAxis = false;
    21.  
    22.       // Parameters.
    23.       ////TODO: add parameters to control ramp up&down
    24.  
    25.       public Vector2 ReadValue(ref InputBindingCompositeContext context)
    26.       {
    27.          var verticalPositiveIsPressed = VerticalPositive.isPressed;
    28.          var verticalNegativeIsPressed = VerticalNegative.isPressed;
    29.          var horizontalNegativeIsPressed = HorizontalNegative.isPressed;
    30.          var horizontalPositiveIsPressed = HorizontalPositive.isPressed;
    31.      
    32.        
    33.          var verticalPositiveValue = verticalPositiveIsPressed ? (InvertVerticalAxis ? -1.0f : 1.0f) : 0.0f;
    34.          var verticalNegativeValue = verticalNegativeIsPressed ? (InvertVerticalAxis ? 1.0f : -1.0f) : 0.0f;
    35.          var horizontalNegativeValue = horizontalNegativeIsPressed ? (InvertHorizontalAxis ? 1.0f : -1.0f) : 0.0f;
    36.          var horizontalPositiveValue = horizontalPositiveIsPressed ? (InvertHorizontalAxis ? -1.0f : 1.0f) : 0.0f;
    37.  
    38.          var result = new Vector2(horizontalNegativeValue + horizontalPositiveValue, verticalPositiveValue + verticalNegativeValue);
    39.  
    40.          return result;
    41.       }
    42.      
    43.    }
    44. }
    45.  

    Then add this composite to the registry like any other InputBinding. on Packages/com.unity.inputsystem/InputSystem/InputManager.cs
    Code (CSharp):
    1.             composites.AddTypeRegistration("AxisStick", typeof(AxisStickComposite));

    Base on the videos on documentation i create a script to test the newly created AxisStickComposite.
    Code (CSharp):
    1.     public class CharacterController : MonoBehaviour
    2.     {
    3.         public InputAction Composite;
    4.         public Vector2 ValueComposite;
    5.  
    6.         public enum ControlType
    7.         {
    8.             KeyboardAndMouse,
    9.             Joystick
    10.         }
    11.      
    12.  
    13.         // Use this for initialization
    14.         void Start (){
    15.             Composite.AppendCompositeBinding("AxisStick")
    16.                 .With("VerticalPositive", "/<Keyboard>/w")
    17.                 .With("VerticalNegative", "/<Keyboard>/s")
    18.                 .With("HorizontalNegative", "/<Keyboard>/a")
    19.                 .With("HorizontalPositive", "/<Keyboard>/d");
    20.             Composite.Enable();
    21.      
    22.  
    23.             Composite.performed += ctx => { ValueComposite = ctx.ReadValue<Vector2>(); };
    24.         }
    25.  
    26.         private void OnEnable()
    27.         {
    28.         }
    29.  
    30.         private void OnDisable()
    31.         {
    32.             Composite.Disable();
    33.         }
    34.  
    35.     }

    for better way to create composite and more interaction and don't mess so much with the source code i think i will try create another interface to read and update boolean that will serve my purpose and hope this help u guys. i'm trying to create other kinds of combination based on this composite aproach and i need help co create a keyboard layout that have axis returned like vertical other horizontal for both "a,d,w,s" and arrow keys. using this 3 composites i have now. i'm still studying the new input system.
     
  4. GilbertoBitt

    GilbertoBitt

    Joined:
    May 27, 2013
    Posts:
    111
  5. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Yup, the Dpad composite performs normalization. Same as for sticks. This is to prevent stuff like your character running faster diagonally (because (1,1) has a magnitude >1) then left/right/up/down :)

    However, I think you have a good point here. The normalization probably isn't desirable in all scenarios. I think this could be best addresses as a simple toggle on the DpadComposite.

    Code (CSharp):
    1. // In DpadComposite
    2. public bool normalize = 1;
    3.  
    4. // In DpadComposite.Process
    5. if (normalize)
    6. {
    7.     // Perform the usual normalization...
    8. }
    9.  
    10. // Setting up
    11. myAction.AppendCompositeBinding("Dpad(normalize=false)")...
    Don't have the code in front of me so not sure composite parameters are already implemented properly (the "normalize=false" part) but that's how it's meant to work.

    Serialization for what in particular?

    The JSON stuff is serialized and deserialized with Unity's own native JSON serializer which, while not being super flexible, does have a couple advantages (speed, GC, etc). For packages meant to be part of Unity's core set, we prefer not creating dependencies on 3rd party libs/packages.
     
    GilbertoBitt likes this.
  6. GilbertoBitt

    GilbertoBitt

    Joined:
    May 27, 2013
    Posts:
    111
    Thanks for this code I will try to use it on my AxisStick composite and change here to add the dpad and normalize alternative and about the normalization I know is not the best thing and not everyone will use normalize axis but have the option todo so is the key to give free will to user. and also could u point me in the right direction to customize the UIElements i didn't understand yet how it works but o hope i can edit to create a more easy way to see composite actions.
     
    Last edited: Jul 12, 2018
  7. GilbertoBitt

    GilbertoBitt

    Joined:
    May 27, 2013
    Posts:
    111
    when i tried your example i get this error returned:

    Exception: No binding composite with name 'Dpad(normalize=false' has been registered
     
  8. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Ah yes, sorry, looking at the code now I see that the composite code doesn't yet support parameters. I've added a TODO item.
     
    GilbertoBitt likes this.