【问题标题】:Switch unity event system target切换统一事件系统目标
【发布时间】:2019-06-14 21:36:30
【问题描述】:

我想用我通过代码在别处手动指定的目标替换统一事件系统的目标。

这是为了允许常规的统一事件为附近的对象适当地触发,即使指针可能不直接在目标上。 (瞄准辅助/指针捕捉/稳定)

我的问题是,即使我用所需的目标更新事件系统的选定游戏对象,统一事件系统也不会触发,因为它仍然认为指针不在目标上方。 (虽然在编辑器事件系统调试对话框中,和高亮效果(针对 UI 元素)相应地触发并显示所选目标已更改。)

//Raycast to snapped object
Physics.Raycast(pos, rot, out hitInfo, 20f);
//Populate pointer event data using current
PointerEventData ped = new PointerEventData(EventSystem.current);

//Update data using snapped objects data
ped.pointerCurrentRaycast = new RaycastResult {
   distance = hitInfo.distance,
   gameObject = focusedObject,
   sortingLayer = hitInfo.transform.gameObject.layer,
   worldNormal = hitInfo.normal,
   worldPosition = hitInfo.point
};

//Update current target - Target changes in unity debug dialog, but has no effect on clickability
EventSystem.current.SetSelectedGameObject(focusedObject, ped);

我错过了什么?

-- 编辑澄清--

我目前使用光线投射和基于距离的代码将指针捕捉到非 GUI 组件上的目标,从而启用基于目标捕捉指针的选择。一旦非 GUI 目标被“捕捉”,我利用 IPointerEnter/Exit/Down/Up/Click 的 ExecuteEvents.ExecuteHierarchy 来根据需要手动触发事件。

但是,对于 GUI 组件目标,如果我利用相同的自定义事件代码,我将失去与更复杂、动态的 GUI 组件交互的能力,而无需多种变通方法并为每个 GUI 元素添加碰撞器。我想避免重新设计 unity 的输入模块以支持指针捕捉,因为一旦指针进入其边界,默认输入模块在 GUI 组件上的开箱即用效果非常好。

-- 编辑 2--

我应该补充一点,我正在使用 Unity 的 HoloLensInputModule 和 HoloLensInput 来处理 UI 交互,同时使用我自己的光线投射来处理非 UI 组件。

看来我需要用我的捕捉代码扩展 HoloLensInput.cs 的 GetGazeScreenPosition(),以便不再需要关心更新事件系统

-- 大部分已解决--

通过扩展 StandaloneInputModule 和 BaseInput 并在其继承结构中覆盖多个方法,我基本上解决了这个问题。 (它很丑但是很有效,而且运行效率更高,因为我能够丢弃不需要的额外 RaycastAll 调用)

问题的关键在于,不仅要覆盖深埋在继承类中的 RaycastAll 调用,还要覆盖任何请求或操作 eventData 时。大部分更改与 GetMousePointerEventData()ProcessMouseEvent() 以及几乎所有链接在其中的方法调用(包括子递归)有关。

话虽如此,滚动条存在问题,它会在最小滚动和最大滚动之间跳转。问题似乎来自 ProcessDrag()'s ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.dragHandler); 之后滑块内部使用的 pointerEventData.position 值

【问题讨论】:

  • 所以你问如何区分你是捕捉到滑块的拇指还是只是拖动区域的一部分?我不认为 Unity 可以为您做太多事情,您必须使用 Graphics Raycasts,如果滑块是最接近的东西,您会查看它的状态并计算您最接近的位置。也许你可以在那个位置执行一个事件。
  • 指针视觉更新的捕捉代码正在工作。在指针捕捉到之后,unity 的独立输入模块的光线投射技术上仍然从相机直接指向前方。这会使指针视觉对象和输入模块目标不对齐,直到释放捕捉为止。指针说我在目标上,当我调用 SetSelectedObject 时它会突出显示,但输入模块的 Down/Click/Up 事件会忽略 SetSelectedObject 以支持其内部光线投射结果。我挖掘得越多,看起来好像我将不得不扩展统一类。

标签: c# unity3d


【解决方案1】:

第一个问题是SetSelectedGameObject 不会向游戏对象发送或转发事件。其目的是更改事件系统作为所选游戏对象跟踪的内容,并可以发送 OnSelectOnDeselect 事件。

如果您想实际执行具有特定目标的事件,则需要使用ExecuteEvents.Execute,它将GameObject 作为事件的目标。

另外,仅修改传入的指针事件是不够的。当鼠标移到任何地方时不会发生任何事件,但您需要检查附近的对象是否需要接收OnMouseEnter 事件!

您需要有运行每一帧的代码,并且能够创建和/或修改PointerEventData,然后使用ExecuteEvents 执行适当的事件

我不知道是否有办法在游戏对象接收到事件之前拦截和丢弃事件,但您需要注意您的系统和内置执行冗余事件。例如,您的系统可能会早于内置系统执行 OnMouseEnter OnMouseStay,而被调用的目标 GameObject 可能需要代码来忽略这些事件的内置执行。

根据您的情况,简单地使用内置事件并使用仅用于接收鼠标事件的更大碰撞器可能更容易。

一种方法是设置Physics.queriesHitTriggers = true;,添加一个带有“更厚”版本的碰撞器的子游戏对象(具体含义可能取决于原始碰撞器),并将其设置为触发器,这样它就不会不要干涉物理。然后,您在该子游戏对象的脚本中实现OnMouseEnter 等,而不是原来的。

【讨论】:

  • 我可能没有很好地传达我的问题的症结,在我的帖子中添加了更多信息/澄清。
  • 我在扩展独立输入模块后添加了更多信息并更新了帖子。
  • @Reahreic 这是很好的信息!当然可以是answer to this question.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多