Unity3d遊戲設計之遊戲內自定義快捷鍵

第一次寫博客,對Unity遊戲開發也只是一個半吊子。俗話說:好記性不如爛筆頭。所以想把自己學過用過的一些知識記錄下來。

很多大型遊戲都會有在遊戲設置裏自定義快捷鍵的功能。最近做項目,策劃提出了這個要求,就開始着手操作了。

       UI部分是使用UGUI開發的,對這個比較熟。爲了實現這個功能,原來是打算用InputField組件來做,但是後面有引發了一串操作上的Bug,看了UI源碼,思考了好久也沒解決。所以決定用最普通的Text組件來實現。下面直接上代碼,然後慢慢解釋。

using UnityEngine.EventSystems;
using UnityEngine.UI;
//需要繼承的接口:IPointerEnterHandler,IPointerExitHandler,IPointerExitHandler,IPointerDownHandler
public class UserDefinedText : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler,IPointerExitHandler,IPointerDownHandler
{
    [HideInInspector]
    public bool isSelecting = false;//是否被選中

    [HideInInspector]
    public Text inputField;//文本顯示
    // Use this for initialization
    void Awake()
    {
        Init();
    }

    private void Init()
    {
        inputField = GetComponent<Text>();

        isSelecting = false;
    }

    string temp;

    void Update()
    {
        if (!isSelecting)
            return;
        
        if (Input.anyKeyDown)
        {
            KeyCode key = InputManager.Instance.GetKeyDownCode();
            if ((key == KeyCode.Mouse0 || key == KeyCode.Mouse1 || key == KeyCode.Mouse2) && currentPointedAt != inputField.gameObject)
            {
                //取消操作
                inputField.text = temp;
            }
            else
            {
                inputField.text = key.ToString();
                if (key == KeyCode.Mouse0 || key == KeyCode.Mouse1 || key == KeyCode.Mouse2)
                    return;
            }
            isSelecting = false;
        }
    }

    #region Events
    private GameObject currentPointedAt = null;

    public void OnPointerEnter(PointerEventData eventData)
    {
        currentPointedAt = eventData.pointerEnter.gameObject;
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        currentPointedAt = null;
    }

    //鼠標擡起,完成修改或者開始修改
    public void OnPointerUp(PointerEventData eventData)
    {
        if (isSelecting)
        {
            //編輯結束 
            isSelecting = false;
        }
        else
        {
            //開始編輯
            isSelecting = true;
            temp = inputField.text;
            inputField.text = "......";
        }
    }

    public void OnPointerDown(PointerEventData eventData)
    {

    }
    #endregion
}

下面是一個捕獲鍵值的管理器,繼承了一個單例。

/// <summary>
    /// 鍵值輸入管理
    /// </summary>
	public class InputManager:Singleton<InputManager>
	{
        public KeyCode cacheKey = KeyCode.None;

        public void Set_KeyCode(string name,KeyCode keycode)
        {

        }
        
        public KeyCode GetKeyDownCode()
		{
			if (Input.anyKeyDown)
			{
				foreach (KeyCode keyCode in Enum.GetValues(typeof(KeyCode)))
				{
					if (Input.GetKeyDown(keyCode))
					{
						//Debug.Log(keyCode.ToString());
						return keyCode;
					}
				}
			}
			return KeyCode.None;
		}
	}

補上在網上學的一個單例類代碼:

/// <summary>
    /// 單例類
    /// </summary>
    public class Singleton<T> : MonoBehaviour where T :Singleton<T>
    {
        private static readonly object systemLock = new object();//線程鎖
        private static T instance;
        public static T Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (systemLock)//鎖一下,避免多線程出問題
                    {
                        instance = FindObjectOfType<T>();
                        if (instance == null)
                        {
                            GameObject obj = new GameObject("_" + typeof(T).Name);
                            DontDestroyOnLoad(obj);
                            instance = obj.AddComponent<T>();
                        }
                        if (instance == null)
                            Debug.LogError("Failed to create instance of " + typeof(T).FullName + ".");
                    }
                }
                return instance;
            }
        }

        void OnApplicationQuit()
        {
            if (instance != null)
            {
                instance = null;
            }
        }

        public static T CreateInstance()
        {
            if (Instance != null) Instance.OnCreate();

            return Instance;
        }

        protected virtual void OnCreate() { }
    }

新建一個Text,掛在腳本,簡單的自定義快捷鍵功能就實現了!


初次發帖,有不足的地方請大家原諒,多寫指正,一起進步,謝謝大家!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章