• 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
1
Question by TrevoriuS · Jan 17, 2013 at 06:23 PM · inputenumgetkey

Input.GetKey() with multiple enum values (C#)

Declaring

private KeyCode ForwardKey = KeyCode.W|KeyCode.UpArrow;

and calling if (Input.GetKey( ForwardKey )) { print("forwardPressed") } during Update isn't working out

Now I want to make a function that splits up the enum into separate values again so I can call getKey for every keycode given.

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

4 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Bunny83 · Jan 17, 2013 at 11:45 PM

Like i said in the comment the KeyCode enum is not a bit mask and therefore the members can't be combined bitwise.

You did this:

 KeyCode.UpArrow == 273 == 100010001
 KeyCode.W       == 119 ==   1110111
 -----------------------------------
 ForwardKey      ==        101110111 == 375 == KeyCode.Joystick2Button5

You have to test your keys seperately. If you want to assign multiple KeyCodes to a certain action, use an array:

 private KeyCode[] ForwardKeys = new KeyCode[] {KeyCode.W, KeyCode.UpArrow};

 public static bool AnyKey(KeyCode[] aKeys)
 {
     foreach(KeyCode K in aKeys)
         if (Input.GetKey(K))
             return true;
     return false;
 }
 
 // Somewhere else
 if (AnyKey(ForwardKeys))
 {
     //
 }

Now you can assign as many KeyCodes as you want.

Comment
Add comment · Share
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
avatar image
0

Answer by doublethink · Jan 17, 2013 at 10:56 PM

With Unity's built in Input Manager you can assign a key and an alternate key for each action known as 'axes' which can be called using a string name. You can also add your own custom actions to the input manager.

Input.GetButton("Fire1")

See http://docs.unity3d.com/Documentation/Manual/Input.html

and http://docs.unity3d.com/Documentation/ScriptReference/Input.GetButton.html

Comment
Add comment · Show 3 · Share
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
avatar image TrevoriuS · Jan 17, 2013 at 11:13 PM 0
Share

I intend to have user settings control what buttons are assigned to which action, making the Input$$anonymous$$anager not an option in this event.

I did find out bitmasking the $$anonymous$$eyCode enum doesn't work because it skips numbers in its value assignments, so passing in values with the | operator results in a different key ins$$anonymous$$d of multiple, later on seperable, values.

avatar image doublethink · Jan 17, 2013 at 11:19 PM 0
Share

Custom input class is probably the way to go then.

avatar image Bunny83 · Jan 17, 2013 at 11:26 PM 0
Share

The reason why this doesn't work is simply the fact that $$anonymous$$eyCode IS NOT a bit mask. An integer bitmask (32 bits) would only allow 32 different keys. As you know we have a little bit more than that ;) (actually 241)

In general an enum doesn't need to be a bitmask. A bitmask is just a very special case. "normal" **enum**erations are just enumerations starting at the value 0 and increasing by 1 for each element.

avatar image
0

Answer by Bluetoungue · Jan 17, 2013 at 11:48 PM

Here i think thisll help I used it myself but here is the C# version of course

if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.UpArrow))

im not sure about the uparrow just mess around with it as all

Comment
Add comment · Share
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
avatar image
2

Answer by TrevoriuS · Jan 17, 2013 at 11:48 PM

Sorry for the lack of comments, but here's what I came up with.

The StackedKeyCodesAsInt generates a valid int that is unique for every keycode combination imaginable, the modifier of 429 is the highest number in the KeyCode enum.

The IntAsExpandedKeyCodes is the backwards conversion, the other functions are wrappers to replace the Input functions. And there's that.

 public static class KeyCodeManager
 {
     public static bool GetKeys( int keycodestack )
     {
         foreach (KeyCode key in IntAsExpandedKeyCodes( keycodestack ))
             if (Input.GetKey( key ))
                 return true;
         return false;
     }
 
     public static bool GetKeysDown( int keycodestack )
     {
         foreach (KeyCode key in IntAsExpandedKeyCodes( keycodestack ))
             if (Input.GetKeyDown( key ))
                 return true;
         return false;
     }
 
     public static bool GetKeysUp( int keycodestack )
     {
         foreach (KeyCode key in IntAsExpandedKeyCodes( keycodestack ))
             if (Input.GetKeyUp( key ))
                 return true;
         return false;
     }
 
     public static int StackedKeyCodesAsInt( KeyCode[] keycodes )
     {
         int output = 0;
         int modifier = 1;
         foreach (KeyCode keycode in keycodes)
         {
             output += modifier * (int)keycode;
             modifier *= 429;
         }
         return output;
     }
 
     public static KeyCode[] IntAsExpandedKeyCodes( int keycodestack )
     {
         List<KeyCode> output = new List<KeyCode>() { (KeyCode)(keycodestack % 429) };
         while (keycodestack > 429)
         {
             keycodestack /= 429;
             output.Add( (KeyCode)(keycodestack % 429) );
         }
         return output.ToArray();
     }
 }
Comment
Add comment · Show 3 · Share
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
avatar image Bunny83 · Jan 18, 2013 at 08:29 AM 0
Share

Do you need to have it as a single value? You know that you can only use 3 values. 4 values doesn'T fit into an int.

I would also recommend to "multiply" by a power-of-two number, that way you can use bit shift operators which are much faster than multiply and especially divide / modulo.

 public static int Stacked$$anonymous$$eyCodesAsInt( $$anonymous$$eyCode[] keycodes )
 {
     int output = 0;
     foreach ($$anonymous$$eyCode keycode in keycodes)
     {
         output <<= 9; // shift left by 9 bits == 512
         output |= (int)keycode & 0x1FF;
     }
     return output;
 }

 public static $$anonymous$$eyCode[] IntAsExpanded$$anonymous$$eyCodes( int keycodestack )
 {
     List<$$anonymous$$eyCode> output = new List<$$anonymous$$eyCode>();
     while (keycodestack > 0)
     {
         output.Add(keycodestack & 0x1FF);
         keycodestack >>= 9;
     }
     return output.ToArray();
 }
avatar image Bunny83 · Jan 18, 2013 at 08:33 AM 0
Share

Btw if you create the single integer because you want to store it in the user configuration, convert between "array and int" only when you save / load the settings and work directly with arrays in your game. If you use it like you have it at the moment you will do the conversion every frame and produce unnecessary garbage.

avatar image TrevoriuS · Jan 18, 2013 at 10:22 AM 1
Share

Thanks for the info :) I'll go with arrays then as it is far easier to maintain, I was focussed on getting this to work the way a bitmask would work and lost track of what was actually useful

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Gamepad input enum eType not working 0 Answers

How to use number keys as a throttle? 0 Answers

Unity C# Two keys pressing one after another not doing a function vice versa 0 Answers

Input.GetKey not working 1 Answer

Catch Ctrl+Z input in Editor 1 Answer

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges