Unity获取RootCanvas大小Rect的问题

今天要做一个多设备适配方案,发现在修改了Canvas Scaler的Reference Resolution后不会立即生效,RectTransfrom的大小不变。

感觉要等到Update后才执行,个人不喜欢这种控制流程。

在网上搜了半天也没发现有人问这个,因为我的某些UI要通过Rect Size来计算大小,可能比较变态吧。所以做一个笔记记录一下。

网上找到一个函数

private void OnRectTransformDimensionsChange()
    {
        Debug.Log("x==========>x:"+GetComponent<RectTransform>().rect);
    }

加到UI Root节点脚本中,可以在大小发生变化的时候调用到。

经过测试。在实例化UI预设的时候就已经改变了好几次大小。

AssetBundle ab = ((DownloadHandlerAssetBundle)www.downloadHandler).assetBundle;
        GameObject uimainobj = (GameObject)UnityEngine.Object.Instantiate(ab.LoadAsset(ab.GetAllAssetNames()[0]));//这里输出了4 次
        uimainobj.name = "UIMain";
        Canvas c = uimainobj.GetComponent<Canvas>();
        c.worldCamera = uiCamera; //这里输出了1次

在这里插入图片描述
Object.Instantiate输出了前4次。
worldCamera 赋值也会调用1次。

看了CanvasScaler.cs源码后,应该是Hander()函数重新计算了大小。
发现OnEnable函数也会调用Hander()函数,所以,我们只要禁用脚本然后打开让他调用一次就好了。

Debug.Log("x========1");
        cScaler.enabled = false;
        //不同的分辨率比率,显示不用的画布大小
        w_h_rate = (float)Screen.width / Screen.height;
        isPad = w_h_rate > pad_rate ? true : false;
        if (isPad)
            cScaler.referenceResolution = new Vector2(padUIWidth, padUIHeight);
        else
            cScaler.referenceResolution = new Vector2(defaultUIWidth, defaultUIHeight);

        cScaler.enabled = true;
        Debug.Log("x========2");

在这里插入图片描述
2133就是正常后的高度,看来可行。

附:CanvasScaler.cs 部分代码

protected override void OnEnable()
    {
      base.OnEnable();
      this.m_Canvas = this.GetComponent<Canvas>();
      this.Handle();
    }

    /// <summary>
    ///   <para>See MonoBehaviour.OnDisable.</para>
    /// </summary>
    protected override void OnDisable()
    {
      this.SetScaleFactor(1f);
      this.SetReferencePixelsPerUnit(100f);
      base.OnDisable();
    }

    /// <summary>
    ///   <para>Handles per-frame checking if the canvas scaling needs to be updated.</para>
    /// </summary>
    protected virtual void Update()
    {
      this.Handle();
    }
    /// <summary>
    ///   <para>Method that handles calculations of canvas scaling.</para>
    /// </summary>
    protected virtual void Handle()
    {
      if ((UnityEngine.Object) this.m_Canvas == (UnityEngine.Object) null || !this.m_Canvas.isRootCanvas)
        return;
      if (this.m_Canvas.renderMode == RenderMode.WorldSpace)
      {
        this.HandleWorldCanvas();
      }
      else
      {
        switch (this.m_UiScaleMode)
        {
          case CanvasScaler.ScaleMode.ConstantPixelSize:
            this.HandleConstantPixelSize();
            break;
          case CanvasScaler.ScaleMode.ScaleWithScreenSize:
            this.HandleScaleWithScreenSize();
            break;
          case CanvasScaler.ScaleMode.ConstantPhysicalSize:
            this.HandleConstantPhysicalSize();
            break;
        }
      }
    }
    /// <summary>
    ///   <para>Handles canvas scaling that scales with the screen size.</para>
    /// </summary>
    protected virtual void HandleScaleWithScreenSize()
    {
      Vector2 vector2 = new Vector2((float) Screen.width, (float) Screen.height);
      float scaleFactor = 0.0f;
      switch (this.m_ScreenMatchMode)
      {
        case CanvasScaler.ScreenMatchMode.MatchWidthOrHeight:
          scaleFactor = Mathf.Pow(2f, Mathf.Lerp(Mathf.Log(vector2.x / this.m_ReferenceResolution.x, 2f), Mathf.Log(vector2.y / this.m_ReferenceResolution.y, 2f), this.m_MatchWidthOrHeight));
          break;
        case CanvasScaler.ScreenMatchMode.Expand:
          scaleFactor = Mathf.Min(vector2.x / this.m_ReferenceResolution.x, vector2.y / this.m_ReferenceResolution.y);
          break;
        case CanvasScaler.ScreenMatchMode.Shrink:
          scaleFactor = Mathf.Max(vector2.x / this.m_ReferenceResolution.x, vector2.y / this.m_ReferenceResolution.y);
          break;
      }
      this.SetScaleFactor(scaleFactor);
      this.SetReferencePixelsPerUnit(this.m_ReferencePixelsPerUnit);
    }
......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值