InputManager输入管理
在利用Unity进行游戏设计时,许多游戏中的流程判断是需要外部输入才能进行的,比如:
①需要鼠标点击才能选中物体;
②需要按下特定按键才能打开菜单;
③需要鼠标转动才能移动视角
…等等;
此类功能的实现我们理所当然地想到了if(检测到对应输入){执行对应操作}
。然而,如果在没处地方都采用if()
的写法,会极大地增加编写难度、代码的质量以及可读性。此时输入管理就排上用场了。
1. 概念
把所有输入的检测都封装到一个类中,统一由这个类来进行管理。当某个输入产生时,这个类会通过某种方法让所有需要这个输入的模块获得该输入并执行对应内容。上述这个类就称为InputManager输入管理。由于一个游戏里往往只需要一个InputManager,因此往往写成单例的形式。
举一个简单的例子,家里的狗狗们会根据主人不同的命令做出不同的行为,当我们需要用代码去模拟一个家庭中好几只狗狗的行为时,可以通过一个InputManager封装主人的命令,只有主人给出了特定的命令时,才去通知各只狗狗该响应主人了。
2. 鼠标的输入管理
以最常见的鼠标左键输入为例:
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.TextCore.Text;
using UnityLearn;
using EventType = UnityLearn.EventType;
namespace UnityLearn
{
// 封装成单例模式
public class InputManager : SingleMono<InputManager>
{
// 是否点到UI
public bool isClickUI = false;
private void Update()
{
// 检测到鼠标左键点下,发送点下相关数据
if (Input.GetMouseButtonDown(0) && !isClickUI)
{
EventManager.Instance.SendEvent(EventType.MouseInput, new EventDataMouseInput()
{
state = EMouseInputState.Down,
key = EMouseInputKey.Left,
position = Input.mousePosition
});
}
// 检测到长按鼠标左键
if (Input.GetMouseButton(0) && !isClickUI)
{
EventManager.Instance.SendEvent(EventType.MouseInput, new EventDataMouseInput()
{
state = EMouseInputState.Stay,
key = EMouseInputKey.Left,
position = Input.mousePosition
});
}
// 检测到松开鼠标左键
if (Input.GetMouseButtonUp(0) && !isClickUI)
{
EventManager.Instance.SendEvent(EventType.MouseInput, new EventDataMouseInput()
{
state = EMouseInputState.Up,
key = EMouseInputKey.Left,
position = Input.mousePosition
});
}
}
}
}
上述代码中,EventManager为事件管理类,其在事件发生时做出响应。会在后续的文章中介绍,此处做理解即可
在这里完成了上述例子中“通知狗狗”的任务,即将事件:鼠标被点击了,和数据:哪个键?点击还是长按?在屏幕什么位置?两者结合发送出去。
3. 事件数据
上述的数据往往被封装为一些事件类,方便配合EventManager使用,本文例子中的事件数据如下所示:
using UnityEngine;
namespace UnityLearn
{
// 事件数据基类
public class EventDataBase
{
}
// 鼠标状态
public enum EMouseInputState
{
Down,
Stay,
Up
}
// 鼠标键值
public enum EMouseInputKey
{
Left,
Mid,
Right
}
// 鼠标数据类
public class EventDataMouseInput : EventDataBase
{
// 鼠标点击状态:按下、长按、松开
public EMouseInputState state;
// 左键右键
public EMouseInputKey key;
// 鼠标位置
public Vector2 position;
}
}