这段时间制作了游戏内的操作系统,主要制作的原因是,在游戏内很多按键是公用的,但是不同位置的处理逻辑不同,比如在最外层界面上,可以使用ESC打开菜单,但是在二级界面里,使用ESC是返回上个界面,如果要使用判断制作的话,会产生很强的耦合性,要在很多位置加入判断逻辑,所以制作了这套按键,先写出代码,下一篇会介绍怎么使用。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class KeystorkeLayer
{
public string registerName;
public Dictionary<KeyCode, Util.NoneParamFunction> keystrokeDict = new Dictionary<KeyCode, Util.NoneParamFunction>();
public Dictionary<int, Util.NoneParamFunction> mouseDict = new Dictionary<int, Util.NoneParamFunction>();
public Dictionary<string, List<Util.NoneParamFunction>> axisDict = new Dictionary<string, List<Util.NoneParamFunction>>();
public HashSet<KeyCode> keyDisableHashSet = new HashSet<KeyCode>();
public HashSet<int> mouseDisableHashSet = new HashSet<int>();
public HashSet<string> axisDisableHashSet = new HashSet<string>();
public int axisCheckFrameCount = 1;
public bool forceTop;
public KeystorkeLayer(string registerName, bool forceTop)
{
this.registerName = registerName;
this.forceTop = forceTop;
}
public void RegisterKeys(List<KeyCode> list, Util.NoneParamFunction callback)
{
if (list == null || list.Count <= 0)
{
return;
}
for (int i = 0; i < list.Count; i++)
{
RegisterKey(list[i], callback);
}
}
public void UnRegisterKeys(List<KeyCode> list)
{
if (list == null || list.Count <= 0)
{
return;
}
for (int i = 0; i < list.Count; i++)
{
UnRegisterKey(list[i]);
}
}
public void RegisterKey(KeyCode key, Util.NoneParamFunction callback)
{
keystrokeDict[key] = callback;
}
public void UnRegisterKey(KeyCode key)
{
if (!keystrokeDict.ContainsKey(key))
{
Debug.LogError("Error Key");
return;
}
keystrokeDict.Remove(key);
}
public void SetKeyEnableState(KeyCode key, bool enable)
{
if (enable)
{
keyDisableHashSet.Remove(key);
}
else
{
keyDisableHashSet.Add(key);
}
}
public void RegisterMouse(int mouseIndex, Util.NoneParamFunction callback)
{
mouseDict[mouseIndex] = callback;
}
public void UnRegisterMouse(int mouseIndex)
{
if (!mouseDict.ContainsKey(mouseIndex))
{
Debug.LogError("Error Mouse");
return;
}
mouseDict.Remove(mouseIndex);
}
public void SetMouseEnableState(int mouseIndex, bool enable)
{
if (enable)
{
mouseDisableHashSet.Remove(mouseIndex);
}
else
{
mouseDisableHashSet.Add(mouseIndex);
}
}
public void RegisterAixs(string axisName, Util.NoneParamFunction firstCallback, Util.NoneParamFunction secondCallback)
{
axisDict[axisName] = new List<Util.NoneParamFunction>();
axisDict[axisName].Add(firstCallback);
axisDict[axisName].Add(secondCallback);
}
public void UnRegisterAixs(string axisName)
{
if(!axisDict.ContainsKey(axisName))
{
Debug.LogError("Error Axis");
return;
}
axisDict.Remove(axisName);
}
public void SetAxisEnableState(string axisName, bool enable)
{
if (enable)
{
axisDisableHashSet.Remove(axisName);
}
else
{
axisDisableHashSet.Add(axisName);
}
}
public void RemoveKeystorkeLayer()
{
for (int i = 0; i < QA.keystrokeMan.keystorkeLayerStack.Count; i++)
{
if (QA.keystrokeMan.keystorkeLayerStack.ElementAt(i) == this)
{
Stack<KeystorkeLayer> tempStack = new Stack<KeystorkeLayer>();
for (int j = 0; j < i; j++)
{
tempStack.Push(QA.keystrokeMan.keystorkeLayerStack.Pop());
}
QA.keystrokeMan.keystorkeLayerStack.Pop();
while (tempStack.Count > 0)
{
QA.keystrokeMan.keystorkeLayerStack.Push(tempStack.Pop());
}
}
}
// 从Stack中删除层时,也从exitLayerStack中删除
if (QA.keystrokeMan.exitLayerStack.Contains(this))
{
for (int i = 0; i < QA.keystrokeMan.exitLayerStack.Count; i++)
{
if (QA.keystrokeMan.exitLayerStack.ElementAt(i) == this)
{
Stack<KeystorkeLayer> tempStack = new Stack<KeystorkeLayer>();
for (int j = 0; j < i; j++)
{
tempStack.Push(QA.keystrokeMan.exitLayerStack.Pop());
}
QA.keystrokeMan.exitLayerStack.Pop();
while (tempStack.Count > 0)
{
QA.keystrokeMan.exitLayerStack.Push(tempStack.Pop());
}
}
}
}
Debug.LogError("PopTopKeystorkeLayer......." + registerName);
}
}
public class KeystrokeManager
{
public Stack<KeystorkeLayer> keystorkeLayerStack = new Stack<KeystorkeLayer>();
public Stack<KeystorkeLayer> exitLayerStack = new Stack<KeystorkeLayer>();
public KeystorkeLayer PushNewKeystorkeLayer(string registerName, bool forceTop = false)
{
registerName = registerName.Replace("(Clone)", "");
Debug.LogError("PushNewKeystorkeLayer......." + registerName);
KeystorkeLayer layer = new KeystorkeLayer(registerName, forceTop);
// 检测顶层是否强制置顶
KeystorkeLayer addLayer = null;
if (keystorkeLayerStack.Count > 0 && keystorkeLayerStack.Peek().forceTop)
{
addLayer = keystorkeLayerStack.Pop();
}
keystorkeLayerStack.Push(layer);
if (addLayer != null)
{
keystorkeLayerStack.Push(addLayer);
}
return layer;
}
public void PopTopKeystorkeLayer()
{
if (keystorkeLayerStack.Count <= 0)
{
Debug.LogError("No Layer Exist");
return;
}
KeystorkeLayer layer = keystorkeLayerStack.Pop();
// 从Stack中删除层时,也从exitLayerStack中删除
if (exitLayerStack.Contains(layer))
{
for (int i = 0; i < exitLayerStack.Count; i++)
{
if (exitLayerStack.ElementAt(i) == layer)
{
Stack<KeystorkeLayer> tempStack = new Stack<KeystorkeLayer>();
for (int j = 0; j < i; j++)
{
tempStack.Push(exitLayerStack.Pop());
}
exitLayerStack.Pop();
while (tempStack.Count > 0)
{
exitLayerStack.Push(tempStack.Pop());
}
}
}
}
Debug.LogError("PopTopKeystorkeLayer......." + layer.registerName);
}
public void RegisterKeys(List<KeyCode> list, Util.NoneParamFunction callback)
{
if (list == null || list.Count <= 0)
{
return;
}
for (int i = 0; i < list.Count; i++)
{
RegisterKey(list[i], callback);
}
}
public void RegisterKey(KeyCode key, Util.NoneParamFunction callback)
{
keystorkeLayerStack.Peek().keystrokeDict[key] = callback;
}
public void UnRegisterKey(KeyCode key)
{
if (!keystorkeLayerStack.Peek().keystrokeDict.ContainsKey(key))
{
Debug.LogError("Error Key");
return;
}
keystorkeLayerStack.Peek().keystrokeDict.Remove(key);
}
public void SetKeyEnableState(KeyCode key, bool enable)
{
if (enable)
{
keystorkeLayerStack.Peek().keyDisableHashSet.Remove(key);
}
else
{
keystorkeLayerStack.Peek().keyDisableHashSet.Add(key);
}
}
public void RegisterMouse(int mouseIndex, Util.NoneParamFunction callback)
{
keystorkeLayerStack.Peek().mouseDict[mouseIndex] = callback;
}
public void UnRegisterMouse(int mouseIndex)
{
if (!keystorkeLayerStack.Peek().mouseDict.ContainsKey(mouseIndex))
{
Debug.LogError("Error Mouse");
return;
}
keystorkeLayerStack.Peek().mouseDict.Remove(mouseIndex);
}
public void SetMouseEnableState(int mouseIndex, bool enable)
{
if (enable)
{
keystorkeLayerStack.Peek().mouseDisableHashSet.Remove(mouseIndex);
}
else
{
keystorkeLayerStack.Peek().mouseDisableHashSet.Add(mouseIndex);
}
}
[System.Obsolete("尽量不要用这个方法,无法通过控制顺序来控制按键时再使用")]
public void SetKeyEnableState(int index, KeyCode key, bool enable)
{
if (index > keystorkeLayerStack.Count - 1 || index < 0)
{
Debug.LogError("Error Index");
}
var layer = keystorkeLayerStack.ElementAt(index);
if (enable)
{
layer.keyDisableHashSet.Remove(key);
}
else
{
layer.keyDisableHashSet.Add(key);
}
}
public void CheckInput()
{
if (keystorkeLayerStack.Count <= 0)
{
return;
}
var layer = keystorkeLayerStack.Peek();
if (Input.anyKeyDown)
{
// 键盘
foreach (var kv in layer.keystrokeDict)
{
if (Input.GetKeyDown(kv.Key) && !layer.keyDisableHashSet.Contains(kv.Key))
{
Debug.LogError(layer.registerName + " - " + kv.Key + "!!!!!!!!!!!!!!!!!!!!!!!");
kv.Value?.Invoke();
return;
}
}
}
if (Input.GetMouseButtonDown(0) && layer.mouseDict.ContainsKey(0) && !layer.mouseDisableHashSet.Contains(0))
{
layer.mouseDict[0]?.Invoke();
return;
}
if (Input.GetMouseButtonDown(1) && layer.mouseDict.ContainsKey(1) && !layer.mouseDisableHashSet.Contains(1))
{
layer.mouseDict[1]?.Invoke();
return;
}
// 沒有處理鎖住的問題
if (Time.frameCount % layer.axisCheckFrameCount == 0)
{
// 每五帧执行一次
foreach (var kv in layer.axisDict)
{
float axisValue = Input.GetAxisRaw(kv.Key);
if (!Mathf.Approximately(axisValue, 0))
{
if (!layer.axisDisableHashSet.Contains(kv.Key))
{
kv.Value[axisValue > 0 ? 0 : 1]?.Invoke();
layer.axisDisableHashSet.Add(kv.Key);
return;
}
} else
{
layer.axisDisableHashSet.Remove(kv.Key);
}
}
}
#if UNITY_EDITOR
if (Input.GetKeyDown(KeyCode.L))
{
Debug.Log("Show Layer Info : " + layer.registerName);
Debug.LogError("=========================");
foreach (var kv in layer.keystrokeDict)
{
Debug.Log(kv.Key + " ---- enable : " + !layer.keyDisableHashSet.Contains(kv.Key));
}
foreach (var kv in layer.mouseDict)
{
Debug.Log(kv.Key + " ---- enable : " + !layer.mouseDisableHashSet.Contains(kv.Key));
}
Debug.Log("=========================");
}
if (Input.GetKeyDown(KeyCode.K))
{
var s = QA.interfaceUIMan.activePageStack.ToArray();
for (int i = 0; i < s.Length; i++)
{
Debug.Log(s[i].Key);
}
}
#endif
}
}