VRTK 重叠Canvas上UIPointer射线穿透的问题(Unity VR)

存在重叠的WordSpace Canvas时,UIPointer射线会穿透Canvas,导致触发错误。

问题探究

解决方法直接跳到最后“解决方法”部分。
2020补充:问题已解决,请移步该文章:https://www.azimiao.com/7509.html

测试场景如下图,有两个重叠的Canvas,分别叫做Canvas3与Canvas4,它们下面各有一个按钮。

场景层级

Canvas上挂一脚本如下:

    void Start(){
        if(this.GetComponentInChildren<Button>()){
            this.GetComponentInChildren<Button>().onClick.AddListener(this.onBtnClick);
        }
    }
    void onBtnClick(){
        Debug.Log("it's" + this.name);
    }

运行后射线指向Canvas3,射线仿佛穿透了Canvas3,打印出的信息是Canvas4。

Log信息

VR与UGUI交互肯定通过EventSystem进行,通过VRTK_UIPointer脚本向底层找,找到了检测碰撞的代码。

代码把射线出发点、方向传递给EventSystem,通过EventSystem.RaycastAll获取射线指到的UI:

//VRTK_VRInputModule.cs
protected virtual List<RaycastResult> CheckRaycasts(VRTK_UIPointer pointer)
{       
    RaycastResult raycastResult = new RaycastResult();
    raycastResult.worldPosition = pointer.GetOriginPosition();
    raycastResult.worldNormal = pointer.GetOriginForward();
    pointer.pointerEventData.pointerCurrentRaycast = raycastResult;

    List<RaycastResult> raycasts = new List<RaycastResult>();
    eventSystem.RaycastAll(pointer.pointerEventData, raycasts);
    return raycasts;
}

既然如此,打印下碰撞结果:

Debug.Log("碰撞到UI了!,共碰到了" + raycasts.Count);
for (int i = 0; i < raycasts.Count; i++)
{
    Debug.Log(raycasts[i].gameObject.name,raycasts[i].gameObject);
}

运行结果

发现返回结果只有Canvas4下的两个组件(截图省略了VRTK自动创建的drag组件)。

关于EventSystem.RaycastAll,官方文档就一句话:使用所有设置过的BaseRaycaster进行碰撞检测。

翻了翻Unity的开源代码,没有找到EventSystem.RaycastAll的具体实现。后来又试着修改了参数属性值,调整了Layer等,也没有作用。

总结:EventSystem.RaycastAll并没有直接返回All碰撞,(也许)按照内部的排序逻辑,把它认为正确的物体吐了出来。

解决方法

  1. 20201216补充:该问题已解决,参考如下文章:

VRTK解决多Canvas射线穿透问题(WorldSpace)

  1. 概率性解决
    将这些重叠Canvas上挂载的Graphic Raycaster组件的Blocking Objects修改为All
    Graphic Raycaster这是概率性解决穿透的方法,有的面板管用,有的面板不好用。
    改为All也无效时,运行后将后面的面板关闭再打开,基本可以解决问题,原因未知,也许和内部排序逻辑有关。

  2. 斩草除根
    在设计阶段避免重叠Canvas同时出现的情况。如果必须出现,那就自求多福吧。

  3. 坐以待毙
    等待着Unity出来给个解释。

梓喵出没博客(azimiao.com)版权所有,转载请注明链接:https://www.azimiao.com/4950.html
欢迎加入梓喵出没博客交流群:313732000

吐槽 Cc

*

*

0位绅士参与评论

  1. Cc07-23 09:31 回复

    “VR与UGUI交互肯定通过EventSystem”
    谢谢博主 这句话帮我大忙了 😳
    PS:请问你的博客怎么搭建的 很好看

    • 野兔07-23 21:19 回复

      非常高兴能帮到你。本博客使用世界上最流行的博客程序WordPress一键搭建。

  2. aby11-28 17:29 回复

    谢谢,帮到我了!