控制ui元素跟随布局组下物体的位置变化(跨父物体访问)

之前做过一个剧情对话模块,其中涉及到了生成对话选项,并有一个箭头来表示用户选择的是哪一个选项。

由于博主是用ugui来做的界面显示,所以不可避免的涉及到了ui坐标控制以及坐标系转换相关的内容。我也使用了几种不同的方法来做实现,我选了一种比较清楚的方法贴在这里。避免以后我自己又忘记了,也给各位铁铁分享一下。


由于子物体是挂载在一个布局组下(这里我用的垂直布局组),所以子物体Rect Transform中的某些属性会交由父物体布局组去控制,这时候在编辑窗口下就无法去手动来拖动了。

旁边的橙色小方块(暂叫它arrow)是用来标记当前选择的选项,他的父物体不是这些选项的父物体,也就是说arrow 和 选项的局部坐标系不同。要想控制arrow能够固定出现在几个选项的右侧,那我们就需要用代码控制,并做一些坐标系转换。

    IEnumerator AdjustArrowPosition(GameObject option)
    {
        // 等待一帧,确保垂直布局组件已经完成调整
        yield return null;

        // 设置箭头的位置
        Vector3 pos = option.transform.position;
        //选项世界坐标系转为屏幕坐标系
        Vector2 screenPos = RectTransformUtility.WorldToScreenPoint(uiCamera, pos);
        //屏幕坐标系转为ui坐标系
        RectTransformUtility.ScreenPointToLocalPointInRectangle(arr.parent as RectTransform, screenPos, uiCamera, out Vector2 localPos);
        arr.localPosition = new Vector3(localPos.x + (option.transform as RectTransform).rect.width / 2 + arrowOffSet, localPos.y, 0f);
    }

这里主要的代码其实就是关于坐标系转换的两个api,其它的可以忽略是关于一些设置的

平常说的几种坐标系:

  • 全局坐标系
  • 局部坐标系
  • 视口坐标系:起点左下,值为0 ~ 1 
  • 屏幕坐标系:起点左下,值跟窗口大小挂钩
  • GUI坐标系:起点左上
  • UGUI坐标系,或者针对Rect的本地坐标系

主要的原因在于世界坐标系 和 ui坐标系不能直接去转换,所以要先转换为屏幕坐标系(转换成视口坐标系也行)

  • 世界转屏幕:RectTransformUtility.WorldToScreenPoint(uiCamera, pos); 
    • 参数类型需要根据canvas的render mode来选择,我用的是摄像机模式,所以需要传入ui摄像机
  • 屏幕转ui:RectTransformUtility.ScreenPointToLocalPointInRectangle(arr.parent as RectTransform, screenPos, uiCamera, out Vector2 localPos);
    • 参数:父物体RectTransform,转换的坐标,摄像机,转换后的坐标

扫描二维码关注公众号,回复: 17499172 查看本文章

访问其它父物体下子物体的位置信息,并做出对应变化的 类似 功能,都可以这样来做,本文举出的 对话选项 只是举例

猜你喜欢

转载自blog.csdn.net/XueZhiXia_/article/details/137820812