现在很多电脑游戏都有自定义按键的功能,这里通过Unity3D实现一个简单的配置按键的功能

开始

一般情况下,我们这样来处理游戏中的输入:

void Update () {
            if (Input.GetKeyDown(KeyCode.W)) Jump();
            if (Input.GetKeyDown(KeyCode.S)) GetDown();
            if (Input.GetKeyDown(KeyCode.A)) Defense();
            if (Input.GetKeyDown(KeyCode.D)) Attack();
    }

现在很多电脑游戏都有自定义按键的功能,这里通过unity实现一个简单的配置按键的功能:

思路

一般玩家修改按键的逻辑如下:

undefined

界面设计

undefined

实现效果

  1. 初始界面如上图:

  2. 点击按键区域后
    undefined

  3. 再按下F键后

undefined

主要代码

public class CustomInput : MonoBehaviour
{
    //assign values by inspector
    public Button jumpBtn;
    public Button getDownBtn;
    public Button defBtn;
    public Button atkBtn;
    //bind keys
    KeyCode jump_key;
    KeyCode getdown_key;
    KeyCode def_key;
    KeyCode atk_key;
    //temp current key
    KeyCode curKey;
    //new key
    KeyCode newKey;
    //current function
    string functionName = string.Empty;
    //clicked button
    Button currentBtn; 

    void Awake()
    {
        GetBindKeys();
    }
    // Use this for initialization
    void Start()
    {
        jumpBtn.onClick.AddListener(JumpBtnClick);
        getDownBtn.onClick.AddListener(GetDownBtnClick);
        defBtn.onClick.AddListener(DefBtnClick);
        atkBtn.onClick.AddListener(AtkBtnClick);
    }
    //when you are setting the input,update will be disabled
    bool isPlaying = true;
    // Update is called once per frame
    void Update()
    {
        if(isPlaying)
        {
            if (Input.GetKeyDown(jump_key)) Jump();
            if (Input.GetKeyDown(getdown_key)) GetDown();
            if (Input.GetKeyDown(def_key)) Defense();
            if (Input.GetKeyDown(atk_key)) Attack();
        }
    }

    bool isWaitingForKey = false;
    void OnGUI()
    {
        if (isWaitingForKey)
        {
            Event e = Event.current;
            if (e.isKey)
            {
                newKey = e.keyCode;
                currentBtn.transform.Find("Text").GetComponent<Text>().text = newKey.ToString();
                PlayerPrefs.SetString(functionName, newKey.ToString());
                isWaitingForKey = false;
                //call when config has changed
                GetBindKeys();
                StartCoroutine(WaitUpdate());
            }
        }
    }
    
    IEnumerator WaitUpdate()
    {
        yield return new WaitForEndOfFrame();
        isPlaying = true;
    }
    //onclick
    void JumpBtnClick()
    {
        currentBtn = jumpBtn;
        isPlaying = false;
        currentBtn.transform.Find("Text").GetComponent<Text>().text = "";
        curKey = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("jump","W"));
        functionName = "jump";
        isWaitingForKey = true;
    }
    void GetDownBtnClick()
    {
        currentBtn = getDownBtn;
        isPlaying = false;
        currentBtn.transform.Find("Text").GetComponent<Text>().text = "";
        curKey = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("getdown", "S"));
        functionName = "getdown";
        isWaitingForKey = true;
    }
    void DefBtnClick()
    {
        currentBtn = defBtn;
        isPlaying = false;
        currentBtn.transform.Find("Text").GetComponent<Text>().text = "";
        curKey = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("defense", "D"));
        functionName = "defense";
        isWaitingForKey = true;
    }
    void AtkBtnClick()
    {
        currentBtn = atkBtn;
        isPlaying = false;
        currentBtn.transform.Find("Text").GetComponent<Text>().text = "";
        curKey = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("attack", "A"));
        functionName = "attack";
        isWaitingForKey = true;
    }
    //detail
    void Jump()
    {
        Debug.Log("我跳了!");
    }
    void GetDown()
    {
        Debug.Log("我趴下了!");
    }
    void Defense()
    {
        Debug.Log("我防御了!");
    }
    void Attack()
    {
        Debug.Log("我攻击了!");
    }
    /// <summary>
    /// get and parse playerprefs
    /// </summary>
    void GetBindKeys()
    {
        jump_key = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("jump", "W"));
        getdown_key = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("getdown", "S"));
        def_key = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("defense", "D"));
        atk_key = (KeyCode)System.Enum.Parse(typeof(KeyCode), PlayerPrefs.GetString("attack", "A"));
        //setting panel display
        jumpBtn.transform.Find("Text").GetComponent<Text>().text = PlayerPrefs.GetString("jump", "W");
        getDownBtn.transform.Find("Text").GetComponent<Text>().text = PlayerPrefs.GetString("getdown", "S");
        defBtn.transform.Find("Text").GetComponent<Text>().text = PlayerPrefs.GetString("defense", "D");
        atkBtn.transform.Find("Text").GetComponent<Text>().text = PlayerPrefs.GetString("attack", "A");
    }
}

TODO:没有进行按键冲突判断