Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by ChiefSlaya · Sep 12, 2014 at 02:00 PM · inputcoroutines

Why is my function/coroutine executing a second time?

I've taken up the task of writing my own Input Manager since the default Unity one doesn't allow ingame rebinding nor retrieval of bound keys. During this process I've come across an issue where triggering a key to be rebound works, but if I press a second key afterwards, it will then try to bind that key.

First off, I have declared two classes to make my life easier here:

 [System.Serializable]
 public class Control {
     public string controlName;
     public string[] buttons;
 
     public Control() {
         buttons = new string[2];
     }
 }
 
 [System.Serializable]
 public class Rebinder {
     public int index;    // Index of control being rebound. -1 means none
     public bool b1;    // Is it button 1 being rebound? false = button 2
     public string key;        // New key to bind
     public ControlRebinder sender;
 
     public Rebinder() {
         index = -1;
         b1 = false;
     }
 }

The Control class is fairly self-explanatory, it acts a lot like an axis in the default Input Manager, with up to 2 buttons bound to one control.
The Rebinder class is only being used once, and is used to store all the necessary rebinding information together. If there's a better way to do this I'd be glad to use it.
I've then created two string arrays, one for containing unity-recognised button on the keyboard (keyList), and one auto-populated at start for controllers (padList). I also have an array of Controls, called controlList.

The Update loop checks if there is a key that needs to be rebound, and if there is it uses a coroutine to get the next input:

 void Update () {
         if(rebinding.index > -1) {
             if(rebinding.key == null || rebinding.key == "") {
                 StartCoroutine(getNextKey(output => rebinding.key = output));
             }
             if(rebinding.key != null && rebinding.key != "") {
                 if(rebinding.b1) {
                     controlList[rebinding.index].buttons[0] = rebinding.key;
                 }
                 else {
                     controlList[rebinding.index].buttons[1] = rebinding.key;
                 }
                 rebinding.index = -1;
                 rebinding.key = null;
                 rebinding.sender.controlRebound(rebinding.key);
                 rebinding.sender = null;
             }
         }
     }

The getNextKey function is here:

 IEnumerator getNextKey(System.Action<string> key) {
         yield return new WaitForSeconds(0.2f);
 
         // Check for controller input
         for(int v = 0; v <= 19; v++) {
             if(Input.GetKey("joystick button "+v)) {
                 for(int x = 1; x <= 4; x++) {
                     if(Input.GetKey("joystick "+x+" button "+v)) {
                         key("joystick "+x+" button "+v);
                         yield break;
                     }
                 }
             }
         }
 
         // Wait until a key is pressed
         while (!Input.anyKey){
             yield return null;
         }
 
         // Go through each valid key and see if it was pressed
         foreach(string k in keyList) {
             if(Input.GetKey(k)) {
                 key(k);
                 yield break;
             }
         }
 
         // If not, unbind the key
         key ("none");
     }

and the function that flags a control for rebinding is here:

 public bool rebindControl(ControlRebinder sender, int controlIndex, int buttonIndex) {
         // Flags a control to be rebound, as long as no other control is being rebound
         if(rebinding.index > -1) {
             return false;
         }
         // Pass control details to rebinding variable
         rebinding.index = controlIndex;
         rebinding.b1 = (buttonIndex == 0)?true:false;
         rebinding.sender = sender;
         return true;
     }

So basically, when I call rebindControl() it will correctly open the right control to be bound, and when I press a button it will correctly accept that input and bind it to the control. However, if I press another button at any time after, without activating another control to be bound, it will load rebinding.key with the key I press. The result of this is that when I next bind a control, it will be bound to the already-loaded key before I press anything.
I am watching the variables in the editor when I do this, and rebinding.index is definitely being set to -1 at the right time, and rebinding.key is definitely being cleared. It will also only occur a second time, not a third.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Waiting for Input via Coroutine 2 Answers

Very fast User Input Game in Unity 1 Answer

Help In Making a SphereCast for 3D Tire! Working RayCast Script included! 0 Answers

Input management with coroutines in a fighting game. 0 Answers

Checking Input on 2 different coroutines at the same time 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges