Multiple keys to GetKey

using UnityEngine;
using System.Collections;

public class WalkAnimation : MonoBehaviour
{
    Animator m_animator;

    void Start ()
    {
        m_animator = GetComponent<Animator> ();
    }

    void Update ()
    {
        bool isWalkingPressed = Input.GetKey ("w");
        m_animator.SetBool ("IsWalking", isWalkingPressed);
    }       
}

I want to make same animation playing when i’m pressing w, a, s, or d. I can’t copy the GetKey script four times cause it says that “isWalkingPressed is already used”. So, how i can set multiple keys to same GetKey code?

I feel like the easiest way to do it would be to write another function that returns true if any of those buttons are being pressed, like so

// it will return TRUE if w, a, s or d are being pressed
  bool AreKeysDown()
  {
  if (Input.GetKey("w") || Input.GetKey("a") || Input.GetKey("s") || Input.GetKey("d"))
  {
  return true; 
  }

  return false;
  }

Then you can assign isWalkingSpeed to that function

// It will be set to TRUE or FALSE depending on whatever AreKeysDown returns
bool isWalkingPressed = AreKeysDown();
1 Like

How new are you to programming? You really shouldn’t start with Unity, because it’s confusing, and there is no tutorial (at least no good one) that covers both programming and unityscript. This problem is pretty easy, if you at least touched any programming language ever.

Is Unity really hard? people keep saying it’s as easy as game development can get.

No, scratch is as easy as game development can get, but still, that doesn’t mean it’s as easy as programming can get, you still have to learn the language

I’m pretty new with c#. I know how to use unity, but on scripts i’m a hopeless

learncs.org

+1

Its because it goes against what a lot of people learn. I can agree that Unity is not a good place to start. I started with Unity and if you look at my first posts [Example] in some cases my issues would of been so easily solved.

I wholeheartedly suggest to learn some programming first coming from someone who made this mistake.
(I also made the mistake of starting with UnityScript, if you’re wondering definitely don’t do that)

3 Likes

Easiest way to it imo is as follows:

bool isWalkingPressed = Input.GetKey ("w") || Input.GetKey ("a") || Input.GetKey ("s") || Input.GetKey ("d");

This will assign true to the variable if one of the GetKey() calls returns true, or false if they are all false.

Also, try to use KeyCodes instead of strings, that will be a lot less error prone :slight_smile:

Just last week I wrote a few NamedInputData classes which would not only handle Binding inputs at runtime, but input masking (as in disable specific inputs so they return false on any class using them. for things like cutscenes or chatboxes when you don’t want scripts accepting input) and grouping more than a couple keycodes to a specific input group.

Abstract class NamedInputData and Extension Methods

DISCLAIMER: I’m only posting part of the code to help provide an example. simply copying/pasting the code won’t work since not all the classes mentioned are provided. The important stuff however is all here, and should be more than enough.

using UnityEngine;
using WoofTools.API;

namespace WoofTools.Models
{
    public abstract class NamedInputData: ScriptableObject, IWoofSavable
    {

        [Tooltip("Should Unity Listen for this Input?")]
        public bool enabled = true;
        [Tooltip("A Description for this Input")]
        public string description = string.Empty;

        virtual protected bool m_Enabled{get{return InputManager.Enabled && enabled;}}

        virtual public bool GetKey             {get{return false;}}
        virtual public bool GetKeyUp           {get{return false;}}
        virtual public bool GetKeyDown         {get{return false;}}
        virtual public bool GetMouseButton     {get{return false;}}
        virtual public bool GetMouseButtonUp   {get{return false;}}
        virtual public bool GetMouseButtonDown {get{return false;}}
        virtual public float GetAxis           {get{return 0f;}}
        virtual public float GetAxisRaw        {get{return 0f;}}

        #region IWoofSavable implementation
        abstract public void Reset();
        abstract public object GetSerilizableObject();
        abstract public bool SetSerilizableObject(object data);
        #endregion

        public static implicit operator bool  (NamedInputData data) { return  data != null && data.GetKey;  }
        public static implicit operator float (NamedInputData data) { return (data != null)?data.GetAxis:0; }
    }

    public static class NamedInputDataExtensions
    {
        /// <summary>
        /// returns whether the Input was released this frame.
        /// returns false if the Input is null (for inputs that are optional)
        /// </summary>
        public static bool TryUp(this NamedInputData data)   {  return data != null && data.GetKeyUp;   }
        /// <summary>
        /// returns whether the Input was pressed this frame.
        /// returns false if the Input is null (for inputs that are optional)
        /// </summary>
        public static bool TryDown(this NamedInputData data) {  return data != null && data.GetKeyDown; }
    }
}

NamedActionInput

using UnityEngine;
using System.Collections.Generic;

namespace WoofTools.Models
{
    [CreateAssetMenu(fileName = "Named Action Input",menuName = "ScriptableObject Asset/Woof Tools/InputManager/Named Action Input")]
    public class NamedActionInputData:NamedInputData
    {
        public List<KeyCode> keys = new List<KeyCode>();
        [SerializeField]private List<KeyCode> defaultKeys = new List<KeyCode>();

        override public bool GetKey     {get{return m_Enabled && keys.Exists(kc=>Input.GetKey(kc));}}
        override public bool GetKeyUp   {get{return m_Enabled && keys.Exists(kc=>Input.GetKeyUp(kc));}}
        override public bool GetKeyDown {get{return m_Enabled && keys.Exists(kc=>Input.GetKeyDown(kc));}}

        override public bool GetMouseButton     {get{return m_Enabled && keys.Exists(kc=>Input.GetKey(kc));}}
        override public bool GetMouseButtonUp   {get{return m_Enabled && keys.Exists(kc=>Input.GetKeyUp(kc));}}
        override public bool GetMouseButtonDown {get{return m_Enabled && keys.Exists(kc=>Input.GetKeyDown(kc));}}

        override protected bool m_Enabled{get{return base.m_Enabled && keys != null;}}

        #region IWoofSavable implementation
        override public void Reset()
        {
            enabled = true;
            keys = new List<KeyCode>(defaultKeys);
        }
        override public object GetSerilizableObject()
        {
            return object[]{enabled,description,keys};
        }
        override public bool SetSerilizableObject(object data)
        {
            object[] input = data as object[];

            if(input == null) return false;
            if(input.Length != 3) return false;
           
            enabled = (bool)input[0];
            description = (string)input[1];
            keys = (List<KeyCode>)input[2];

            return true;
        }
        #endregion
    }

}

Example Use

Here is a one of my classes using the NamedInputData (optionally I might add) on lines 78 and 84

using System.Collections;
using UnityEngine;
using WoofTools.API;
using WoofTools.Attributes;
using WoofTools.Events;
using WoofTools.Utilities;


namespace WoofTools.Models
{
    public class WaitForSecondsCommandPayload :smile:elegatorCommandPayload
    {
        [SerializeField][ReadOnly]private float m_countdown;
        [SerializeField][ReadOnly]private bool  m_paused = false;
       
        [Tooltip("How long should the wait be for?")]
        public float duration = 1;
        [Tooltip("You can optionally use a unique timescale, or leave the field empty to use Unity's Time.timScale")]
        public TimeScale timeScale = null;
        [Tooltip("You can optionally provide an Input that will pause the countdown")]
        public NamedInputData pauseInput = null;
        [Tooltip("You can optionally provide an Input that will abort the countdown")]
        public NamedInputData abortInput = null;
       
        public FloatEvent OnCountdownBegin   = new FloatEvent();
        public FloatEvent OnCountdownUpdate  = new FloatEvent();
        public FloatEvent OnCountdownFinish  = new FloatEvent();
        public BoolEvent  OnCountdownPause   = new BoolEvent();
        public FloatEvent OnCountdownAborted = new FloatEvent();
       
        private float DeltaTime { get { return (timeScale != null) ? Time.unscaledTime * timeScale.scale:Time.deltaTime; } }
       
       
        override public void Execute ()
        {
            if(parameters == null)return;
            if(parameters.runner == null)return;
            m_paused = false;
           
            Coroutine handle = parameters.Coroutine;
            parameters.runner.RestartCoroutine(WaitThread(duration), ref handle);
            parameters.Coroutine = handle;
        }
       
        public void Pause() 
        {
            if(parameters == null)return;
            if(parameters.runner == null)return;
            if(parameters.Coroutine == null)return;

            m_paused = !m_paused;
            OnCountdownPause.Invoke(m_paused);
        }
       
        public void Stop()
        {
            if(parameters == null)return;
            if(parameters.runner == null)return;
            if(parameters.Coroutine == null)return;
           
            Coroutine handle = parameters.Coroutine;
            parameters.runner.TryStopCoroutine(ref handle);
            parameters.Coroutine = handle;

            float abortedTime = m_countdown;
            m_countdown = duration;
            m_paused = false;
            OnCountdownAborted.Invoke(abortedTime);
        }
       
        private IEnumerator WaitThread(float waitTime)
        {
            m_countdown = waitTime;
            OnCountdownBegin.Invoke(waitTime);
           
            while (m_countdown>0)
            {
                if(abortInput.TryDown())
                {
                    Stop();
                    yield break;
                }

                if(pauseInput.TryDown())
                {
                    Pause();
                }

                if(!m_paused) 
                {
                    m_countdown = Mathf.MoveTowards(m_countdown,0,DeltaTime);
                    OnCountdownUpdate.Invoke(m_countdown);
                }
               
                yield return null;
            }
           
           
            Coroutine handle = parameters.Coroutine;
            parameters.runner.TryStopCoroutine(ref handle); 
            parameters.Coroutine = handle;

            m_countdown = duration;
            m_paused = false;

            OnCountdownFinish.Invoke(0);
        }
    }
}

The NamedActionInputData stores a list of KeyCodes they can be any number of keycodes and can be changed at runtime (whether its the keys binded to the Input group, or whatever Input group a script is using).

with your example you could write the code as:

public NamedActionInputData walkingInput;

...

m_animator.SetBool ("IsWalking", walkingInput);

the implict operator will make the needed GetKey calls leaving you to just create the NamedInputData instance, map the keycodes it’ll listen to in the inspector and attach it to your script.

Thank you for your comment. Here you put multiple keys and any of these key pressed it will work. What is if I want to use multiple keys in a way that if A,B and C will be pressed, then only it will work. If I press A, it will not. Please help me with this.