UFL9-1——输入控制模块的具体实现
UFL9-1——输入控制模块的具体实现
输入控制模块的基本原理(以键盘为例)
-
制作
InputManager
单例模式管理器1
2
3
4public class InputManager : BaseManager<InputManager>
{
private InputManager() { }
} -
在输入管理器中进行按键检测
要检测哪个按键,就在帧更新方法内监听对应的方法,帧更新方法需要在添加到公共Mono模块的帧更新内
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18private InputManager()
{
MonoManager.Instance.AddUpdateListener(InputUpdate);
}
// 开启或者关闭输入模块管理的检测
public void StartOrCloseInputManager(bool isCheckInput)
{
this.isCheckInput = isCheckInput;
}
private void InputUpdate()
{
if (Input.GetKeyDown(KeyCode.W))
{
Debug.Log("按下W键")
}
} -
利用事件中心分发事件
先到事件中心声明对应的事件名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18/// <summary>
/// 事件类型枚举
/// </summary>
public enum E_EventType
{
/// <summary>
/// 键盘按下某一个键按下的事件
/// </summary>
E_Keyboard_Up,
/// <summary>
/// 键盘某一个键抬起的事件
/// </summary>
E_Keyboard_Down,
/// <summary>
/// 键盘某一个键长按的事件
/// </summary>
E_Keyboard,
}要监听键盘的哪个键输入,就在帧更新方法内调用检测键盘按键输入时传入这个按键的枚举值
检测到输入时,需要将监听到的按键枚举值通过事件中心传递出去,让外部识别1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32using UnityEngine;
public class InputManager : BaseManager<InputManager>
{
private InputManager()
{
MonoManager.Instance.AddUpdateListener(InputUpdate);
}
private void InputUpdate()
{
CheckKeyCode(KeyCode.W);
CheckKeyCode(KeyCode.A);
CheckKeyCode(KeyCode.S);
CheckKeyCode(KeyCode.D);
CheckKeyCode(KeyCode.H);
CheckKeyCode(KeyCode.J);
CheckKeyCode(KeyCode.K);
CheckKeyCode(KeyCode.L);
}
private void CheckKeyCode(KeyCode key)
{
if (Input.GetKeyDown(key))
EventCenter.Instance.EventTrigger(E_EventType.E_Keyboard_Down, key);
if (Input.GetKey(key))
EventCenter.Instance.EventTrigger(E_EventType.E_Keyboard, key);
if (Input.GetKeyUp(key))
EventCenter.Instance.EventTrigger(E_EventType.E_Keyboard_Up, key);
}
} -
在希望处理输入逻辑的位置监听事件
例如要监听W键按下的事件,就需要监听事件中心上的
E_EventType.E_Keyboard_Down
事件,根据传入的枚举值来判断是否是W键按下注:为了便于移除监听方法,请不要使用匿名函数来监听事件中心的事件!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class Main : MonoBehaviour
{
void Start()
{
EventCenter.Instance.AddEventListener<KeyCode>(E_EventType.E_Keyboard_Down, CheckKeyCode);
}
private void CheckKeyCode(KeyCode key)
{
switch (key)
{
case KeyCode.W:
print("W键按下");
break;
default:
break;
}
}
}但是要注意,由于输入管理器继承的单例基类是懒汉模式的,此时还没有调用过输入模块,因此,这时输入检测是不会生效的
-
提供输入系统检测开关
声明一个
bool
变量表示是否开启输入检测,默认是关闭的,声明一个方法来为外部提供开启或关闭输入检测的功能1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29private bool isCheckInput;
private InputManager()
{
MonoManager.Instance.AddUpdateListener(InputUpdate);
}
// 开启或者关闭输入模块管理的检测
public void StartOrCloseInputManager(bool isCheckInput)
{
this.isCheckInput = isCheckInput;
}
private void InputUpdate()
{
//如果外部未开启检测功能,就不检测输入
if (!isCheckInput)
return;
CheckKeyCode(KeyCode.W);
CheckKeyCode(KeyCode.A);
CheckKeyCode(KeyCode.S);
CheckKeyCode(KeyCode.D);
CheckKeyCode(KeyCode.H);
CheckKeyCode(KeyCode.J);
CheckKeyCode(KeyCode.K);
CheckKeyCode(KeyCode.L);
}然后,在外部开启这个输入检测,之后输入检测就会生效
注:为了便于移除监听方法,请不要使用匿名函数来监听事件中心的事件!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class Main : MonoBehaviour
{
void Start()
{
InputManager.Instance.StartOrCloseInputManager(true);
EventCenter.Instance.AddEventListener<KeyCode>(E_EventType.E_Keyboard_Down, CheckKeyCode);
}
private void CheckKeyCode(KeyCode key)
{
switch (key)
{
case KeyCode.W:
print("W键按下");
break;
default:
break;
}
}
}此时按下W键就会输出:
鼠标按键的监听
先到事件中心声明对应的事件名
1 | /// <summary> |
仿照键盘输入的监听,声明对应的监听鼠标按键输入的方法,
监听到鼠标输入时需要触发事件中心对应的事件,并将监听到的按键通过事件中心传递出去,方便外部识别
要监听鼠标的哪个键的输入,就在帧更新方法内调用检测鼠标按键输入时传入这个按键的ID
1 | private bool isCheckInput; |
假设要监听鼠标按键按下的事件,就需要监听事件中心上的E_EventType.E_Mouse_Down
事件,根据传入的mouseID
来识别是哪个按键的输入
注:为了便于移除监听方法,请不要使用匿名函数来监听事件中心的事件!
1 | public class Main : MonoBehaviour |
鼠标左右键分别按下时,输出:
轴的监听
直接在帧更新方法内不停的触发事件并传递某个轴的值即可,需要传递哪个轴的值就在帧更新方法内触发事件并传递出去
1 | private InputManager() |
然后在外部监听对应的事件即可获取值
注:为了便于移除监听方法,请不要使用匿名函数来监听事件中心的事件!
1 | public class Main : MonoBehaviour |
按下AD键输出内容:
抛出问题
- 多开关,分别控制键盘、鼠标、热键检测的开关 —— 思路:加
bool
变量 - 按下、抬起、长按3种类型的事件合3为1 —— 思路:通过参数传递当前事件类型
- 如何制作改键功能