我编写了一个“热键”类,它可以轻松地用一些修饰符键(shift、ctrl、cmd.)计算单个给定的键。
与其他任何KeyControl一样,该类能够判断热键是否正在按下,或者是否在当前帧上按下/释放热键。也能够在发生这些事情时发出C#事件。
代码工作起来很有魅力,除了一件事,例如,如果我想检查我创建的实例的热键Ctrl+Z,如下所示:
var ctrlZ = new Hotkey(Key.Z, ModifierKeys.LeftShift);
(Key是一个used,ModifierKeys是一个标记自定义枚举,它定义了最常用的修饰符键)。
然后,为了检查一下,我只需要打电话:
if (ctrlZ.isPressed) { // code here... }
当我按下组合Ctrl+Shift+Z时,就会出现问题,当我不希望这样做时,上面的代码计算为true,因为我需要用Ctrl+Z热键做一件事,用Ctrl+Shift+Z做另一件事(它重叠)。
我正在使用新的输入系统,为了评估热键,我只需迭代修饰符KeyControl对象的列表,并检查它们是否与给定的Key同时按下。
那么问题是:,我如何才能防止这种重叠?
我尝试了最基本的解决方案,即将所有未使用的修饰符KeyControl对象添加到另一个列表中,并检查这些对象是否没有按下,但我想知道是否有比那样检查它更容易和更有效的解决方案(它是在Update循环中完成的,所以,如果许多热键是这样计算的,我认为这可能会导致一些开销)。
发布于 2021-08-31 22:58:13
好吧,虽然我说过我决定离开它,因为它是在我的评论丹尼尔Bereza,我有最后一个想法,这似乎是真正的解决方案,我正在寻找,它成功了!
我决定自己回答自己,以防其他人需要解决这个问题。
基本上,我所做的是检查每个帧是否热键的修饰符键被按下和,如果没有其他的按下。这是由2个循环完成的(一个用于需要按下的修饰符,另一个用于不需要按下的修饰符)。
为了替换这些循环,我使用了按位操作。诀窍是存储一个标记枚举(在我的例子中是ModifierKeys类型),它告诉您当前按下了哪些修饰符键,另一个标记枚举是互补的,让我们这样说:
private static ModifierKeys pressedModifiers
private static ModifierKeys unpressedModifiers
这两个字段通过先前绑定到每个修饰符键的InputAction事件进行更新,因此当按下修饰符键时,可以将ModifierKey标志添加到pressedModifiers中,同时更新互补的unpressedModifiers。
然后检查它是否被按下,例如,它很简单:
public bool IsPressed => modifiersToBePressed == pressedModifiers && ((int) (unpressedModifiers & modifiersToBePressed) == 0) && Keyboard.current[this.Key].isPressed
仅此而已,如果您想检查它是否已在当前框架上按下或发布,只需更改Keyboard.current[this.Key].isPressed部件即可满足您的需要。
我希望我解释得很清楚。我测试了它,它似乎像预期的那样工作,除非有一些我没有考虑到的东西。我还测试了性能,而另一种方法在600个热键评估中平均花费了100到200微秒,而这个解决方法只需要5-15微秒。这对我来说是个很大的进步。
https://stackoverflow.com/questions/68991067
复制相似问题