Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved New Input System 2D Vector Composite question

Discussion in 'Input System' started by symorian, Nov 26, 2021.

  1. symorian

    symorian

    Joined:
    Jun 7, 2017
    Posts:
    69
    Hi,

    I'm porting my old project to a newer one and I decided to migrate to the new Input System.

    Within the old system it was easy to check whether a KeyCode was pressed within an IF statement and then would fire actions accordingly.

    My problem is, I'm using 2D Vector Composite for my basic character movement directions in order to retain Vector2(GetAxisRaw("Horizontal"), GetAxisRaw("Vertical")) structure to be able to use passed values.

    But at the same time, I'm using

    Code (CSharp):
    1. if (Input.GetKeyDown(KeyCode.UpArrow))
    2.         {
    3.             Debug.Log("Up Arrow is pressed");
    4.         }
    elsewhere.

    I cannot figure out how to check a binding/member of 2D Vector Composite to be true or false(in this context "up") when it is pressed.

    I'll be glad if someone can help me out.

    Thank you!
     
  2. symorian

    symorian

    Joined:
    Jun 7, 2017
    Posts:
    69
    A small update,

    While I can call some methods if I use it like this,

    Code (CSharp):
    1. if(directionsInput.y > 0){
    2. Debug.Log("Up arrow is pressed");
    3. }
    where directionsInput is a Vector2 returned by another method, I don't think this is the most versatile solution and it is prone to errors. Because when I inspect it in the console, it is called multiple/varying times per frame which is not a reliable thing where on the other hand old Input.GetKeyDown is made sure to be triggered only once.

    Another thing is,
    I can get the name of the binding for "up" with,
    inputManager.Hero.Movement.bindings[1]
    where index of Up Arrow is 1.
    Yet, this has no use for me to check whether it is pressed and released like a bool. :(
     
  3. symorian

    symorian

    Joined:
    Jun 7, 2017
    Posts:
    69
    Hi again,

    Since my question has received no reply, I suspect that I'm expecting to get an answer for a wrong question or I'm totally missing a few fundamentals here and there.

    I better ask it this way,

    I am using Arrow Keys with my custom character controller, including UpArrow being assigned for both triggering some jump-specific methods at some point + calculating upwards Vectoral motion.

    I am fine with getting expected directional results by using

    Code (CSharp):
    1. inputManager.Player.Movement.performed += myParameter => MovementControls(myParameter.ReadValue<Vector2>());
    which, returns the directional info in Vector3 for me to be processed in other parts. It works well.

    And... I also created another "Jump" action under actions and also reassigned UpArrow to its binding as you can see in the below picture.



    So this way, I'm able to listen for that binding and use it in Update() to trigger other methods. This is also fine.

    As an output I can now read both Movement directions and also check if UpArrow is pressed/released by simply checking boolean with,

    Code (CSharp):
    1. if (playerInput.actions["Jump"].triggered)
    2.         {
    3.             Debug.Log("up arrow key was pressed");
    4.  
    5.         }
    Going back to my Original post, I cannot find any other way to listen for "triggered" state of UpArrow from within Movement action since it returns a Vector2 and also defining all movement buttons separately and then joining them to form a Vector2 info looked as if overdoing it.

    The thing I'm asking is, is this a proper way to define inputs in my case?
    Will I have some mess when I want a "rebinding" function to be added in my game in later phases?

    Can I make it so that the player can automatically bind a button of his choice to both bindings (UpArrow under 2d Vector and UpArrow under jump) at the same time? :rolleyes:

    In short, my whole point is,
    I'm using Arrow Keys(UpArrow in this context ) for both GetAxisRaw & Input.GetKey in the old system for the same button. Trying to convert it into the new system.



    Thank you all.
     
  4. Serge_Billault

    Serge_Billault

    Joined:
    Aug 26, 2014
    Posts:
    190
    I am going to try and do my best to land this in a diplomatic way. God be witness that I will take the heat for all the ones who were afraid to answer because there are no other way to put this other than by putting it for what it is.

    Historically, with the advent of multi-platforms development, studios were more and more driven to abstract inputs logic so as to think in terms of actions (here, right there, I said it, it was the most important part: in terms of actions), instead of controls triggered because the controls available and their natures vary from one platform to another.

    So they began to implement systems where they wouldnt need any more to bother about which controls is in which state, but where they would simply ask if an action was triggered and by which amount, be it because of a button, an axis, a hamster running in a wheel, or all three at the same time. Because all we care in the end is: is an action being requested.

    By wanting to return to the old paradygm where you ask for a particular control, you are effectively fighting against the very purpose of using the new input system.
     
  5. symorian

    symorian

    Joined:
    Jun 7, 2017
    Posts:
    69

    First of all thanks for the reply.
    Actually I get the idea behind the "new" input system yet, my understanding and skills in coding don't let me find my way through that jungle. That is the purpose of it for me to write here to get help :)
    A couple weeks ago I also asked for help at another topic where I was somehow confused and even came to a conclusion that what I knew on the topic was completely garbage, later sometime realizing that it was just a silly mistake and overlooking I did somewhere and found the solution with some "help".

    That's why I'm asking how to emulate or rewrite that old functionality in the new system, "in a correct way". I'm pulling my hair out to come closer to it and I did so within 2 days time. But not so perfect.

    I guess 2D Vector composite used with a stick is something different than a button press on a keyboard. Alas, as I said above my code interpretation ability is still very low (that I've just recently started to use standard Events and Delegates) so that I'm losing the grasp of that whole Input System at some point when trying to set things up.

    So if you can be kind enough at least to point me to a proper direction to start from, I would be glad.
    Other than this, I'm a seaman and apart from my heavy daily duties I can barely find time and availability to access web to learn things and research. Thank you for the nice diplomatic attitude, though. :)
     
  6. Serge_Billault

    Serge_Billault

    Joined:
    Aug 26, 2014
    Posts:
    190
    Since the new input system is designed to think in term of action, it's with actions that you have to work with.
    Most of the time (there are other ways), one fetch a reference on an action through an InputActionReference.
    This InputActionReference (which can be a serialized field of a mono-behaviour, or be initialized by code) hold a reference to the action you wish to monitor.

    Thus when people want to monitor if a jump action is activated (be it because a single binding to the jump action causes the action value to change or be it because of any combination of different bindings to the same action) they invoke the ReadValue<>() method of said action (InputActionReference.action.ReadValue<>()).

    The advantage of using InputActionReference.action.ReadValue<>() instead of Input.GetKey() is that whatever platform you build for, whatever controls are available on the platform you build for, you will always get a value for your action while Input.GetKey() might not work on platforms that dont offer a keyboard as an available peripheral.

    Of course, your bindings and Input settings will have to match the diversity of platforms you plan to support. So if your reference to the jump action is declared as InputActionRefererence m_jump,
    you test your action with a statement involving m_jump.action.ReadValue().
     
    symorian likes this.
  7. symorian

    symorian

    Joined:
    Jun 7, 2017
    Posts:
    69
    I can totally follow you and agree with what you've written.

    Actually in my second post I'd written an example line of code of mine which is I think uses this logic.

    Code (CSharp):
    1. if(directionsInput.y > 0){
    2. Debug.Log("Up arrow is pressed");
    3. }
    When I check this condition with (which I did so)

    ReadValue<Vector2>().y > 0

    In Update() or in a separate method that is being called inside update, the console displays that it is being triggered/called various times.

    My question was, is this the expected behaviour(because that it is not one-shot) and would it cause me trouble to process the rest of the code relying on that if statement?

    Because, GetKeyDown or wasPressedThisFrame(?) and sorts always check that type of condition for once which looks more trustworthy. Or is it not?

    Currently I'm watchkeeping.
    Once I'm back in my room, I better share my input code if it makes it easier for you to help me out?

    Thank you.
     
  8. https://docs.unity3d.com/Packages/com.unity.inputsystem@1.2/manual/Migration.html
    This tells you everything you need to know how to approach a move from the Input manager to Input System in a fairly simple case.
    But I urge you (and in my opinion, Unity should have doing the same) to let the old system go and try to build up your thinking about controls in the new way. Actions first, bindings second. Once it clicks and you can build your input handling around this, it can do wonders.
    One of the best things in the new InputSystem that you don't have to poll the state anymore, you can simply react to changes.
     
    symorian likes this.
  9. symorian

    symorian

    Joined:
    Jun 7, 2017
    Posts:
    69
    That was actually one of the many pages that I have saved to read later. I had a look at it again following the link and it's obvious that I have to read it thoroughly. Thanks for the reminder!

    That's why instead of using "BOTH" as an option in Player settings, I've just chosen to use New Input System to get rid of the old setup as quick as I can.

    Thank you!
     
  10. symorian

    symorian

    Joined:
    Jun 7, 2017
    Posts:
    69
    Thank you both for heads-up!
    I now got it working after thinking over it carefully. Again, the devil is in the details. :D

    @Serge_Billault
    I wasn't using the ReadValue<>() method to its full potential and just spiced it up with a nice Jump On/Off method using its .y value and it works like a charm now. I have a clean Movement Action that only consists of 2D Vector Composite.

    @Lurking-Ninja thank you for pointing me out to that reference page. I'd simply forgotten about that and probably will refer to it occasionally!

    :)
     
  11. LunaTrap

    LunaTrap

    Joined:
    Apr 10, 2015
    Posts:
    120
    Thanks for opening this thread, I was looking exactly for this question, thanks for posting some answers @symorian