开发程序的时候经常会出现更改操作方式的情况,这种时候就需要将操作模式以事件的方式注册到管理输入事件的类中,方便可以随时切换和调用
using System;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 记录鼠标事件的的结构体
/// </summary>
public struct InputMouseEvent
{/// <summary>/// 鼠标事件名称/// </summary>public string name;/// <summary>/// 鼠标左键按下事件/// </summary>public Action<bool> mouseDown;/// <summary>/// 鼠标左键抬起事件/// </summary>public Action<bool, Vector3> mouseUp;/// <summary>/// 鼠标左键拖拽事件/// </summary>public Action<bool,Vector3> mouseDrag;/// <summary>/// 鼠标右键按下事件/// </summary>public Action<bool> rightMouseDown;/// <summary>/// 鼠标右键抬起事件/// </summary>public Action<bool, Vector3> rightMouseUp;/// <summary>/// 鼠标右键抬起事件/// </summary>public Action<bool, Vector3> rightMouseDrag;/// <summary>/// 鼠标滚轮滚动事件/// </summary>public Action<bool,float> mouseScroll;/// <summary>/// 初始赋予事件名称的构造函数,赋予全部为空的事件,需要添加的事件在构造函数()后的{}大括号中添加/// </summary>/// <param name="name"></param>public InputMouseEvent(string name){this.name = name;mouseDown = b => { };mouseDrag = (b,v) => { };mouseUp = (b, v) => { };rightMouseDown = b => { };rightMouseUp = (b, v) => { };rightMouseDrag = (b, v) => { };mouseScroll = (b,flt) => { };}
}public class InputManager : MonoBehaviour
{private static InputManager main;public static InputManager Main{get{if (main == null){main = new GameObject("InputManager").AddComponent<InputManager>();main.Init();}return main;}}/// <summary>/// 保存的鼠标事件库,用来存放全部的鼠标事件,以字典的方式保存方便根据事件名称查找/// </summary>public Dictionary<string,InputMouseEvent> inputMouseEvent = new Dictionary<string, InputMouseEvent>();/// <summary>/// 保存的键盘点击事件库,用来存放全部的鼠标事件,以字典的方式保存方便根据事件名称查找/// </summary>public Dictionary<string, Dictionary<KeyCode, Action>> inputKeyDownEvent = new Dictionary<string, Dictionary<KeyCode, Action>>();/// <summary>/// 保存的键盘持续按下的事件库,用来存放全部的鼠标事件,以字典的方式保存方便根据事件名称查找/// </summary>public Dictionary<string, Dictionary<KeyCode, Action>> inputKeyEvent = new Dictionary<string, Dictionary<KeyCode, Action>>();/// <summary>/// 当前执行的鼠标事件/// </summary>InputMouseEvent runMouseEvent;/// <summary>/// 当前执行的键盘点击事件/// </summary>Dictionary<KeyCode, Action> runKeyDownEvent = new Dictionary<KeyCode, Action>();/// <summary>/// 当前执行的键盘持续按下事件/// </summary>Dictionary<KeyCode, Action> runKeyEvent = new Dictionary<KeyCode, Action>();bool dragMouse;bool dragRightMouse;Vector3 clickMousePos;Vector3 clickRightMousePos;List<string> mouseEventList = new List<string>();List<string> keyDownEventList = new List<string>();List<string> keyEventList = new List<string>();//先注册事件,然后调用这个方法传入想要执行的事件名,会自动覆盖上一个执行的事件public void ChangeInputEvent(string eventName){if (inputMouseEvent.ContainsKey(eventName)){mouseEventList.Add(eventName);}if (inputKeyDownEvent.ContainsKey(eventName)){keyDownEventList.Add(eventName);}if (inputKeyEvent.ContainsKey(eventName)){keyEventList.Add(eventName);}runMouseEvent = inputMouseEvent[mouseEventList[mouseEventList.Count - 1]];runKeyDownEvent = inputKeyDownEvent[keyDownEventList[keyDownEventList.Count - 1]];runKeyEvent = inputKeyEvent[keyEventList[keyEventList.Count - 1]];}//不想执行事件的时候,就调用这个方法解除执行,会自动执行上一个被覆盖的事件public void RemoveInputEvent(string eventName){mouseEventList.Remove(eventName);keyDownEventList.Remove(eventName);keyEventList.Remove(eventName);runMouseEvent = inputMouseEvent[mouseEventList[mouseEventList.Count - 1]];runKeyDownEvent = inputKeyDownEvent[keyDownEventList[keyDownEventList.Count - 1]];runKeyEvent = inputKeyEvent[keyEventList[keyEventList.Count - 1]];}void Init(){inputMouseEvent.Add("空", new InputMouseEvent("空"));inputKeyDownEvent.Add("空", new Dictionary<KeyCode, Action>());inputKeyEvent.Add("空", new Dictionary<KeyCode, Action>());ChangeInputEvent("空");}void Update(){//用来判断当前鼠标是否在UI上的神奇方法,目前先注释//bool pointEnter = BaseCanvas.Main.GetPointEnter();bool pointEnter = false;Ray ray = CameraController.Main.camera.ScreenPointToRay(Input.mousePosition);if (Input.GetMouseButtonDown(0)){clickMousePos = Input.mousePosition;if (!pointEnter) { dragMouse = true; }runMouseEvent.mouseDown(pointEnter);}if(Input.GetMouseButtonUp(0)){dragMouse = false;runMouseEvent.mouseUp(pointEnter, Input.mousePosition - clickMousePos);}if (dragMouse){//获取鼠标移动距离的时候可以使用pos.magnituderunMouseEvent.mouseDrag(pointEnter, Input.mousePosition - clickMousePos);}if (Input.GetMouseButtonDown(1)){clickRightMousePos = Input.mousePosition;if (!pointEnter) { dragRightMouse = true; }runMouseEvent.rightMouseDown(pointEnter);}if (Input.GetMouseButtonUp(1)){dragRightMouse = false;runMouseEvent.rightMouseUp(pointEnter, Input.mousePosition - clickRightMousePos);}if (dragRightMouse){//获取鼠标移动距离的时候可以使用pos.magnituderunMouseEvent.rightMouseDrag(pointEnter, Input.mousePosition - clickRightMousePos);}runMouseEvent.mouseScroll(pointEnter,Input.mouseScrollDelta.y);foreach (var item in runKeyDownEvent){if (Input.GetKeyDown(item.Key)){item.Value();}}foreach (var item in runKeyEvent){if (Input.GetKey(item.Key)){item.Value();}}}
}
下面是一个使用方法的案例:
InputMouseEvent mouseEvent;Dictionary<KeyCode, Action> keyEvent = new Dictionary<KeyCode, Action>();void Init(){mouseEvent = new InputMouseEvent("编辑路径"){mouseDown = MouseDown,mouseUp = MouseUp,mouseDrag = MouseDrag,rightMouseDown = MouseDown,rightMouseUp = MouseUp,rightMouseDrag = MouseDrag,};keyEvent = new Dictionary<KeyCode, Action>{{ KeyCode.W , ClickW },{ KeyCode.S , ClickS },{ KeyCode.A , ClickA },{ KeyCode.D , ClickD },};InputManager.Main.inputMouseEvent.Add("编辑路径", mouseEvent);InputManager.Main.inputKeyEvent.Add("编辑路径", keyEvent);}void OnEnable(){InputManager.Main.ChangeInputEvent("编辑路径");}private void OnDisable(){InputManager.Main.RemoveInputEvent("编辑路径");}void MouseDown(bool pointEnter){}void MouseUp(bool pointEnter, Vector3 pos){}void MouseDrag(bool pointEnter,Vector3 pos){}void ClickW(){}void ClickS(){}void ClickA(){}void ClickD(){}