游戏开发日志 (其ℂ(5,2)):输入、选中

发表于: 4/7/2023

Selection

鼠标框选单位

Input System

:::default no-icon 一遇到鼠标,事情就会变的复杂起来 :::

在曾经的文章里已经做了一个选择功能的雏形,到了现在,可以发现,这也只能算是一个原型。什么,这么长时间过去了还没弃坑!

确实是走了一段很难说是不是歧途的弯路。

简单的说,作为一个RTS类型为源头的游戏,鼠标的重要性不必再说(什么你是触摸屏?),指指点点、框框A上去;而不巧,我们要做的东西有几套不同的逻辑都要用这一套交互,还要在彼此间切换。形象点说,类似建筑规划与单位操作之间的关系。

状态机

聪明如你未必想不到这个办法,来分割不同的逻辑。 想不到也没关系,快来学

internal InputState inputState = InputState.DefaultInputState;
void Update()
{
    var next = inputState.GetNext() ?? inputState.Handle(this);

    if (next != null)
    {
        inputState.OnLeave(this);
        next.OnEnter(this);
        inputState = next;
    }
}

这下眼不见心不烦了!我们还可以像那些牛逼哄哄的项目一样,{一个State 就写一个 文件^一个 文件 就写一个 State}了!{可喜可贺^おめでと},{可喜可贺^おめでと}! 同时我们还能轻易支持状态打断.SetNext().GetNext()和优雅的状态进入、离开的处理。

这样就把一个隐藏的问题摆到了我们的面前:是否有必要每个状态都自己实现一遍对输入的处理?

输入系统-选择

理想情况下,我们会想要一个专门的系统来处理一切用户的输入和输入带来的结果,而只需要给指定事件提供其对应的功能。 在能够改键的游戏里应该很常见,不如说作为游戏引擎应该是会有这样的插件的吧?

但是很不幸,本作——如果完成发布的话,有很多不同的框选/选择操作;姑且透露下,如果有过RTS游戏经验的人,很容易就能想到“选择单位 -> 下达命令”这个流程,而我偏要加入一个“下达命令 -> 选择单位执行”流程。 而即便不提同样的行为不同的功能,如果有一个编队面板,我想让这个面板也支持“选择单位执行”,那么给面板写一个逻辑再手动打断“选择单位”的状态显然不是一个好主意。 我们面对的东西要更迫切一些。

class InputSystem : MonoBehaviour
{
    public GameObject[] SelectedGameObjects { get; private set; }
    public Event OnSelectionChanged;
    public void SetSelection(GameObject[] selections);
    
    void Update()
    {
        //... HandleSelction()
    }
}

这样的一个东西大概就能满足我们的需要了,根据需要可能要加入Predication来清除不需要的选择,或者是干脆一点用LayerMask筛选;以及—— 关闭这套功能的开关 总有些时候会考虑不周来酒吧里点炒饭嘛是不是。

输入系统-命令

如上所说,这样一个InputSystem如果只是处理下鼠标选择,那么也稍显贫弱了。 那么便来考虑下“常规”的命令、改键相关的东西,不过直接做一个命令表键位映射什么的跟我们的项目不是很搭——不同的输入状态分割了不同的输入命令。

由此暂且构想这样一个东西

InputSystem.Instance.AddCommand(commandName: "attack-intent", defaultKey: KeyCode.A, handler);

而显然是允许一个commandName具有多个handler随状态进行切换的,那么考虑多处的重复commandName,也许可以用其首字母作为默认键。!!War3的先进经验!! 随后就在运行时把不存在的 “命令-键位 映射” 输出保存到什么文件,此后可高枕而无忧也!