zoukankan      html  css  js  c++  java
  • UGUI 逻辑以及实用性辅助功能

      UGUI 有它的实用性, 可是也存在理解上的困难, 因为它在面板上的显示内容根据布局而变动, 如果不深入理解它的设计原理, 估计每次要进行程序上的修改都需要进行一次换算和测试过程.

    1. 设置某UI的尺寸.

      它并没有提供一个直接设置尺寸的API, 因为想要改变UI大小根据需求有不同的方法, 不同的方法会造成不同的结果. 比如可以修改 anchorMin / anchorMax , 或是修改 offsetMax / offsetMin, 又或是修改 sizeDelta, 有多种可能的方案, 可是某些修改是会对子节点的UI造成很大影响的, 我们需要找到一个比较稳定的修改方法. Anchors相关的变量会造成子节点变化, 不应该修改它, 而offsetMax / offsetMin 跟 sizeDelta 其实可以看成是相同的表达, 只不过表现形式不一样. 那么简化的函数就是 :

    public static void SetSize(RectTransform rect, Vector2 targetSize)
    {
        var originSize = rect.rect.size - rect.sizeDelta;
        var makeSizeDelta = targetSize - originSize;
        rect.sizeDelta = makeSizeDelta;
    }

      只需要几次减法即可设置非常方便, 它的逻辑就是依据sizeDelta的性质来计算的 : sizeDelta 代表的是Rect现在的大小与原始Rect的大小的差, 公式应该是:

      RectSize(原始大小) + sizeDelta = RectSize(当前大小)

      那么我们要设置一个目标大小, 只需要先计算出原始大小, 然后用 RectSize(目标大小) - RectSize(原始大小) = sizeDelta 即可得出要得到目标大小时的sizeDelta, 直接设置给rect的sizeDelta 即可, 这样计算又简单, 又不需要改动锚点等, 保证修改过程的稳定性... 顺带一提 sizeDelta 绝对不是UI的大小, 是UI现在的大小跟UI的原始大小的差, 只有在锚点 anchorMin , anchorMax 相等时, UI 的原始大小为0, sizeDelta才跟UI大小相等.

    2. 用UI的某个 Pivot 去跟父节点UI的某个 Pivot去对齐

      看起来很乱来的需求, 看图理解:

      子UI红色的 Pivot为 (0, 1), 而我们要把它的 (0.5, 1.0) 与父UI 的(0, 1) 的位置对齐, 也就是红色UI的中间顶部跟白色UI的左上角对齐, 修改方式也有很多种, 通过修改 anchoredPosition 应该是最稳健的方法了, 因为它不会修改任何造成子节点UI变化的变量. 简化的计算方法如下: 

    public static Vector2 SyncPovitToParent(RectTransform rect, Vector2 pivot, Vector2 parentPivot)
    {
        var parent = rect.parent as RectTransform;
        var offsetInParent = MathTools.Multiple(MathTools.Multiple(rect.pivot, rect.rect.size) - MathTools.Multiple(pivot, rect.rect.size), rect.localScale);
        var parentOffset = MathTools.Multiple(parentPivot, parent.rect.size) - MathTools.Multiple(rect.pivot, parent.rect.size);
        return MathTools.VectorAdd(parentOffset, offsetInParent);
    }

      MathTools 只是做了Vector对应变量的乘法加法等功能.

      这个方法的好处在于你不需要修改 Pivot 变量, 只通过移动UI的方式来进行对齐, 没有用到距离, 除法等... 

    rect.anchoredPosition = SyncPovitToParent(rect, new Vector2(0.5f, 1), new Vector2(0, 1));

      rect 就是要对齐的红色UI, new Vector2(0.5f, 1) 是选定红色UI的Pivot位置( rect的原始Pivot为(0, 1), 计算前后不变 ),  new Vector2(0, 1) 是选定父节点UI的Pivot位置, 计算后rect相应的位置与父节点相应位置重合. 逻辑如下 : 

    1. 计算在当前Pivot下怎样移动rect才能使当前 Pivot 与父节点相应 Pivot 点重合

    var parentOffset = MathTools.Multiple(parentPivot, parent.rect.size) - MathTools.Multiple(rect.pivot, parent.rect.size);

      直接用 parent.rect.size 作为坐标系, 乘上 parentPivot, rect.pivot 作为向量, 相减得出 rect 要移动的向量 parentOffset. 

    2. 计算在当前Pivot下, 怎样移动rect 才能让当前Pivot 与选定红色UI的 Pivot 位置重合

    var offsetInParent = MathTools.Multiple(MathTools.Multiple(rect.pivot, rect.rect.size) - MathTools.Multiple(pivot, rect.rect.size), rect.localScale);

      使用当前UI大小作为坐标系, 乘上 rect.pivot, pivot 作为向量, 相减得到 rect 坐标系中的偏移量, 然后再乘以当前坐标的缩放 rect.localScale 就得到在父UI中 rect 要移动的向量 offsetInParent.

    两个向量相加得到最后要偏移的量 anchoredPosition ...

  • 相关阅读:
    Web用户控件
    ASP.Net状态管理读书笔记--思维导图
    网站教学 提纲总结到ajax结束后面还有
    ajax文本空输入显示用户信息
    Ajax 下拉列表联动显示
    用Ajax删除的做法
    Findora:引入保密性和可审计的区块链
    角逐云计算的“新黄金十年”,谁将胜出?
    区块链世界的中心应该是什么?
    边缘计算2.0时代存在哪些挑战?
  • 原文地址:https://www.cnblogs.com/tiancaiwrk/p/11766387.html
Copyright © 2011-2022 走看看