首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >防止热键重叠[统一]

问防止热键重叠[统一]
EN

Stack Overflow用户
提问于 2021-08-30 22:47:50
回答 2查看 188关注 0票数 1

我编写了一个“热键”类,它可以轻松地用一些修饰符键(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循环中完成的,所以,如果许多热键是这样计算的,我认为这可能会导致一些开销)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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微秒。这对我来说是个很大的进步。

票数 0
EN

Stack Overflow用户

发布于 2021-08-30 23:39:35

虽然医生们认为这并不完全是由联合实现的,因为它讨论的是合成键将左右键合并到shiftKey中,而不是任何与此相关的东西,但我认为有多种方法可以更好地为您自己实现这一点--也许可以直接连接到控制中的输入事件或扩展方法之一。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68991067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档