如何暂时禁用MixedRealityToolkit.InputSystem?
How to temporarly disable MixedRealityToolkit.InputSystem?
我想在某些转换期间禁用所有输入,例如,一旦用户单击了一个按钮。
当然我可以禁用该按钮,但我正在寻找更通用的解决方案以避免看到每个按钮再次出现相同的错误。
我试过 PushInputDisable
/ PopInputDisable
,这似乎是我要找的东西,但它在弹出后 inputsimulationservice
出现错误,并且总体上大多数输入事件遗憾的是,从输入系统引发的问题没有插入到禁用堆栈中。
我可以制作一个实现所有接口并使用 PushModalInputHandler
的输入处理程序,但对于我想要实现的目标来说,这似乎有点矫枉过正。
另外,它可能无法捕捉语音命令。
任何简单的解决方案?
您可以使用以下代码来禁用和启用输入系统:
public class DisableInputSystemTest : MonoBehaviour
{
private IMixedRealityInputSystem inputSystem = null;
private IMixedRealityInputSystem InputSystem
{
get
{
if (inputSystem == null)
{
MixedRealityServiceRegistry.TryGetService<IMixedRealityInputSystem>(out inputSystem);
}
return inputSystem;
}
}
public void DisableInputSystem()
{
InputSystem.Disable();
}
public void EnableInputSystem()
{
InputSystem.Enable();
}
}
请注意,在最新的 mrtk_development
分支中有一个错误(问题 5085),在 re-enabling 之后你会得到很多空指针,提示“NullReferenceException:对象引用未设置为一个对象的实例
Microsoft.MixedReality.Toolkit.Input.FocusProvider.RegisterPointers(Microsoft.MixedReality.Toolkit.Input.IMixedRealityInputSource 输入源)(位于 Assets/MixedRealityToolkit.Services/InputSystem/FocusProvider.cs:689)“
要修复,请将以下代码从 MixedRealityInputSystem.Initalize()
移至 MixedRealityInputSystem.Enable()
的开头:
MixedRealityInputSystemProfile profile = ConfigurationProfile as MixedRealityInputSystemProfile;
if (profile.PointerProfile != null)
{
if (profile.PointerProfile.GazeProviderType?.Type != null)
{
GazeProvider = CameraCache.Main.gameObject.EnsureComponent(profile.PointerProfile.GazeProviderType.Type) as IMixedRealityGazeProvider;
GazeProvider.GazeCursorPrefab = profile.PointerProfile.GazeCursorPrefab;
// Current implementation implements both provider types in one concrete class.
EyeGazeProvider = GazeProvider as IMixedRealityEyeGazeProvider;
}
else
{
Debug.LogError("The Input system is missing the required GazeProviderType!");
return;
}
}
else
{
Debug.LogError("The Input system is missing the required Pointer Profile!");
return;
}
现在关于这个的任何事情,它修复了吗?
GitHub 上的后续问题,看起来这个案例没有做任何事情,提供了任何适当的解决方案。
如果我用 Juila 提供的这个修复代码,我会收到错误消息:
混合现实设备管理器已注册! ArgumentException:已添加具有相同键的项目。键:平 Microsoft.MixedReality.Toolkit.Utilities.ArticulatedHandPose.LoadGesturePose (ArticulatedHandPose.cs:218)
看起来这个东西在 MRTK 的核心中更深入。
有趣的是,当我从失去焦点状态回到 Unity 应用程序时,我在一个 HoloLens 上丢失了语音命令,但在另一个 HoloLens 上,相同的版本,相同的 OS 版本,它有效非常清楚。
建立在 , if you need to disable the Input System inside an MRTK callback function (e.g., inside an Interactable's OnClick event 回调之上),你必须在协程中调用 InputSystem.Disable();
,否则你会遇到错误。例如:
// OnClick callback for MRTK's Interactable
public void OnClick()
{
// This call causes the following Exception to be raised (and not caught):
// "InvalidOperationException: Collection was modified; enumeration operation may not execute."
//Microsoft.MixedReality.Toolkit.CoreServices.InputSystem.Disable();
// This call successfully disables the input system with no errors
StartCoroutine(DisableCoroutine());
}
IEnumerator DisableCoroutine()
{
yield return null;
Microsoft.MixedReality.Toolkit.CoreServices.InputSystem.Disable();
}
这种方法的唯一缺点是至少需要另一个帧才能禁用 MRTK 输入系统,但至少不会出现任何错误。
作为参考,所遇到错误的堆栈跟踪如下:
InvalidOperationException: Collection was modified; enumeration operation may not execute.
System.ThrowHelper.ThrowInvalidOperationException (System.ExceptionResource resource) (at :0)
System.Collections.Generic.List`1+Enumerator[T].MoveNextRare () (at :0)
System.Collections.Generic.List`1+Enumerator[T].MoveNext () (at :0)
Microsoft.MixedReality.Toolkit.BaseDataProviderAccessCoreSystem.LateUpdate () (at Assets/MRTK/Core/Services/BaseDataProviderAccessCoreSystem.cs:69)
Microsoft.MixedReality.Toolkit.MixedRealityToolkit+<>c.b__66_0 (Microsoft.MixedReality.Toolkit.IMixedRealityService service) (at Assets/MRTK/Core/Services/MixedRealityToolkit.cs:963)
Microsoft.MixedReality.Toolkit.MixedRealityToolkit.ExecuteOnAllServicesInOrder (System.Action`1[T] execute) (at Assets/MRTK/Core/Services/MixedRealityToolkit.cs:1034)
Microsoft.MixedReality.Toolkit.MixedRealityToolkit.LateUpdateAllServices () (at Assets/MRTK/Core/Services/MixedRealityToolkit.cs:963)
Microsoft.MixedReality.Toolkit.MixedRealityToolkit.LateUpdate () (at Assets/MRTK/Core/Services/MixedRealityToolkit.cs:638)
我想在某些转换期间禁用所有输入,例如,一旦用户单击了一个按钮。
当然我可以禁用该按钮,但我正在寻找更通用的解决方案以避免看到每个按钮再次出现相同的错误。
我试过 PushInputDisable
/ PopInputDisable
,这似乎是我要找的东西,但它在弹出后 inputsimulationservice
出现错误,并且总体上大多数输入事件遗憾的是,从输入系统引发的问题没有插入到禁用堆栈中。
我可以制作一个实现所有接口并使用 PushModalInputHandler
的输入处理程序,但对于我想要实现的目标来说,这似乎有点矫枉过正。
另外,它可能无法捕捉语音命令。
任何简单的解决方案?
您可以使用以下代码来禁用和启用输入系统:
public class DisableInputSystemTest : MonoBehaviour
{
private IMixedRealityInputSystem inputSystem = null;
private IMixedRealityInputSystem InputSystem
{
get
{
if (inputSystem == null)
{
MixedRealityServiceRegistry.TryGetService<IMixedRealityInputSystem>(out inputSystem);
}
return inputSystem;
}
}
public void DisableInputSystem()
{
InputSystem.Disable();
}
public void EnableInputSystem()
{
InputSystem.Enable();
}
}
请注意,在最新的 mrtk_development
分支中有一个错误(问题 5085),在 re-enabling 之后你会得到很多空指针,提示“NullReferenceException:对象引用未设置为一个对象的实例
Microsoft.MixedReality.Toolkit.Input.FocusProvider.RegisterPointers(Microsoft.MixedReality.Toolkit.Input.IMixedRealityInputSource 输入源)(位于 Assets/MixedRealityToolkit.Services/InputSystem/FocusProvider.cs:689)“
要修复,请将以下代码从 MixedRealityInputSystem.Initalize()
移至 MixedRealityInputSystem.Enable()
的开头:
MixedRealityInputSystemProfile profile = ConfigurationProfile as MixedRealityInputSystemProfile;
if (profile.PointerProfile != null)
{
if (profile.PointerProfile.GazeProviderType?.Type != null)
{
GazeProvider = CameraCache.Main.gameObject.EnsureComponent(profile.PointerProfile.GazeProviderType.Type) as IMixedRealityGazeProvider;
GazeProvider.GazeCursorPrefab = profile.PointerProfile.GazeCursorPrefab;
// Current implementation implements both provider types in one concrete class.
EyeGazeProvider = GazeProvider as IMixedRealityEyeGazeProvider;
}
else
{
Debug.LogError("The Input system is missing the required GazeProviderType!");
return;
}
}
else
{
Debug.LogError("The Input system is missing the required Pointer Profile!");
return;
}
现在关于这个的任何事情,它修复了吗?
GitHub 上的后续问题,看起来这个案例没有做任何事情,提供了任何适当的解决方案。
如果我用 Juila 提供的这个修复代码,我会收到错误消息:
混合现实设备管理器已注册! ArgumentException:已添加具有相同键的项目。键:平 Microsoft.MixedReality.Toolkit.Utilities.ArticulatedHandPose.LoadGesturePose (ArticulatedHandPose.cs:218)
看起来这个东西在 MRTK 的核心中更深入。
有趣的是,当我从失去焦点状态回到 Unity 应用程序时,我在一个 HoloLens 上丢失了语音命令,但在另一个 HoloLens 上,相同的版本,相同的 OS 版本,它有效非常清楚。
建立在 InputSystem.Disable();
,否则你会遇到错误。例如:
// OnClick callback for MRTK's Interactable
public void OnClick()
{
// This call causes the following Exception to be raised (and not caught):
// "InvalidOperationException: Collection was modified; enumeration operation may not execute."
//Microsoft.MixedReality.Toolkit.CoreServices.InputSystem.Disable();
// This call successfully disables the input system with no errors
StartCoroutine(DisableCoroutine());
}
IEnumerator DisableCoroutine()
{
yield return null;
Microsoft.MixedReality.Toolkit.CoreServices.InputSystem.Disable();
}
这种方法的唯一缺点是至少需要另一个帧才能禁用 MRTK 输入系统,但至少不会出现任何错误。
作为参考,所遇到错误的堆栈跟踪如下:
InvalidOperationException: Collection was modified; enumeration operation may not execute. System.ThrowHelper.ThrowInvalidOperationException (System.ExceptionResource resource) (at :0) System.Collections.Generic.List`1+Enumerator[T].MoveNextRare () (at :0) System.Collections.Generic.List`1+Enumerator[T].MoveNext () (at :0) Microsoft.MixedReality.Toolkit.BaseDataProviderAccessCoreSystem.LateUpdate () (at Assets/MRTK/Core/Services/BaseDataProviderAccessCoreSystem.cs:69) Microsoft.MixedReality.Toolkit.MixedRealityToolkit+<>c.b__66_0 (Microsoft.MixedReality.Toolkit.IMixedRealityService service) (at Assets/MRTK/Core/Services/MixedRealityToolkit.cs:963) Microsoft.MixedReality.Toolkit.MixedRealityToolkit.ExecuteOnAllServicesInOrder (System.Action`1[T] execute) (at Assets/MRTK/Core/Services/MixedRealityToolkit.cs:1034) Microsoft.MixedReality.Toolkit.MixedRealityToolkit.LateUpdateAllServices () (at Assets/MRTK/Core/Services/MixedRealityToolkit.cs:963) Microsoft.MixedReality.Toolkit.MixedRealityToolkit.LateUpdate () (at Assets/MRTK/Core/Services/MixedRealityToolkit.cs:638)