Unity Binding冲突解决探究

主要参考:

可能存在冲突的几种情况:

  1. 同一Action下不同binding引用同一个control,且都非组合绑定
    在这里插入图片描述

    • button action:仅触发一次performed
    • value action:触发多次performed,有几个相同control就触发几次
    • passthrough:同value(不过注意按键释放值归0时passthrough也会触发performed)
  2. 不同Action下引用同相同control,且都非组合绑定
    在这里插入图片描述

    • 不存在冲突(不论什么action type),会触发各自Action的performed
  3. 同一Action下不同binding引用同不同control
    在这里插入图片描述

    • button:仅触发一次performed
    • value:例如绑定了JKL,按下J不放时触发一次perforemed;继续按下KL不放,不触发;然后依次释放JK,则又会触发两次performed;最后释放L不触发performed。
    • passthrough:比如绑定JKL,每个键的按压释放都会触发一次performed。


    说明: 这种情况和组合绑定情况有些类似,比如jkl,(j,k,l)的任何组合都认定为不同值,都会触发value或passthrough的值变更触发performed(jkl变成全0时不触发value类型的performed,但passthrough依旧会)。

    但是对于value来说,似乎跟binding在Action中的顺序有关,比如上面jkl绑定,如果按lkj顺序释放是不触发performed的,就比较奇怪。

  4. 不同Action下引用同一个control,且binding复杂度不同
    在这里插入图片描述

    • 两action都设为value、button:
      • 单按space键,触发fireCube;
      • 按ctrl+space,触发fireSphere;overrideModifiedFirst=true时,space+ctrl也触发fireSphere。
    • 也就是触发了高复杂度的Action,低复杂度action不再触发,这对组合绑定的冲突都同样使用。
    • 不考虑passthrough的情况,否则结果无预期效果。
  5. 同一Action下不同binding引用同一个control,且冲突的binding复杂度不同
    在这里插入图片描述

    • 按ctrl+space只会触发一次fireSphere
    • 按space会触发一次fireSphere
    • 对于overrideModifiedFirst=true,按space不放后会触发一次fireSphere,但此时再按ctrl,不会再触发fireSphere
  6. 上面4和5的结合
    在这里插入图片描述

    • 只按space,fireCube和fireSphere都会触发一次,这满足上面2和5的结论
    • 但按ctrl+space, fireCube和fireSphere也都会触发一次,这与4的结论不符合。因为从4、5情况的冲突解决想法,如果有高复杂度的绑定被消费了,冲突的低复杂度绑定就不再消费了,所以6这种案例可能是未曾考虑的边界情况,或许是bug。

总结:
总之,不考虑上面 第6点 这种特列,当存在冲突,优先高复杂度binding触发action,其所包含的冲突control就不同时触发其他action了。

而非组合绑定时,action下绑定多个相同control的binding,是允许同时触发多次action的。不同Action下引用同相同control,也允许同时触发两个action的。这两种不属于触发冲突,是由用户来控制的。
在这里插入图片描述

而对于同一Action下不同binding引用同不同control,官方文档举了个例子,如同时绑定手柄的左右扳机键,同时扣动时,会进行消除歧义的操作:当动作尚未启动时,它将对具有非默认值的第一个输入做出反应。一旦接收到这样的输入,它将开始跟踪该输入的来源。在动作正在进行时,如果接收到来自当前正在跟踪的控件以外的输入,它将检查输入是否具有比当前正在跟踪的控件更大的幅度。如果是这样,动作将从当前控件切换到具有更强输入的控件。

而如果当前control存在冲突且非"最激活"的,就会略过defaultInteraction处理,所以对于上面 第3点,依次按下jkl后,如果先释放kl是不会触发action的,只有先释放j才会触发action,但之后哪个control能拿到"最激活"的control,似乎和action上binding的顺序有关。
在这里插入图片描述
考虑到源码中处理controlStateChange的代码比较乱,而且modified 组合绑定曾出现过大bug,目前还不能相信官方对于按键冲突的处理没有问题,所以在使用Action绑定时,尽量避免冲突的发生。

Unity中,协程(Coroutine)是一种用于执行异步操作的特殊函数,可以在游戏循环中暂停和恢复执行。当多个协程同时执行时,可能会出现冲突问题。 解决协程冲突的方法如下: 1. 使用yield return语句的方式来等待其他协程完成。通过在协程中使用yield return语句,可以使该协程暂停执行,并等待其他协程完成后再继续执行。这样可以避免多个协程同时对同一资源进行操作。 2. 使用锁(Lock)机制对共享资源进行保护。当多个协程需要同时访问或修改同一个共享资源时,可以使用锁机制来确保同一时间只有一个协程可以操作该资源。通过在访问或修改共享资源的代码块前后加锁,可以防止冲突发生。 3. 使用消息队列(Message Queue)来管理协程执行顺序。通过将需要执行的协程放入消息队列中,并按照一定的规则依次执行,可以避免多个协程同时执行导致的冲突问题。可以使用Unity提供的Coroutine类或自定义的消息队列来实现这个功能。 4. 避免在协程中使用阻塞操作。阻塞操作会导致协程无法继续执行,并可能引发冲突问题。可以考虑将阻塞操作放在子线程中执行,或使用异步操作来处理。 5. 合理规划协程的执行顺序。在设计游戏逻辑时,可以合理规划协程的执行顺序,避免多个协程同时对同一资源进行操作。 通过以上方法,可以有效地解决Unity中协程冲突的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值