ContentSizeFitter使用Preferred Size来设置RectTransform不能立即生效,必须要等一帧,也可以利用OnRectTransformDimensionsChange的回调方法。
但是这么做还是很恶心,最好还是能同步的计算出它的区域,一般我们可能会横向纵向的嵌套Layout。
主要就是 LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform); 这一句。 如果不想用下面的脚本。 也可以在取RectTransofrm的size之前加上这一句
unity版本:5.3.5
不废话了直接上代码啦。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
using UnityEngine; using System.Collections; using UnityEngine.UI; using FitMode = UnityEngine.UI.ContentSizeFitter.FitMode; using UnityEngine.EventSystems; using System; [RequireComponent(typeof(ContentSizeFitter))] public class ContentImmediate :MonoBehaviour { private RectTransform m_RectTransform; private RectTransform rectTransform { get { if (m_RectTransform == null) m_RectTransform = GetComponent<RectTransform>(); return m_RectTransform; } } private ContentSizeFitter m_ContentSizeFitter; private ContentSizeFitter contentSizeFitter { get { if (m_ContentSizeFitter == null) m_ContentSizeFitter = GetComponent<ContentSizeFitter>(); return m_ContentSizeFitter; } } //立即获取ContentSizeFitter的区域 public Vector2 GetPreferredSize () { LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform); return new Vector2(HandleSelfFittingAlongAxis(0),HandleSelfFittingAlongAxis(1)); } private float HandleSelfFittingAlongAxis(int axis) { FitMode fitting = (axis == 0 ? contentSizeFitter.horizontalFit : contentSizeFitter.verticalFit); if (fitting == FitMode.MinSize){ return LayoutUtility.GetMinSize(rectTransform, axis); }else{ return LayoutUtility.GetPreferredSize(rectTransform, axis); } } } |
然后是测试的代码, 同步把gameobject挂在Layout下,同步计算出它的size。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using UnityEngine; using UnityEngine.UI; using System.Collections; public class Test : MonoBehaviour { public GameObject momo; public GameObject ruoruo; void Start () { //同步的把两个gameobject挂在layout下面 GameObject go1 = GameObject.Instantiate<GameObject>(momo); go1.transform.SetParent(transform,false); GameObject go2 = GameObject.Instantiate<GameObject>(ruoruo); go2.transform.SetParent(transform,false); ContentImmediate content = GetComponent<ContentImmediate>() ?? gameObject.AddComponent<ContentImmediate>(); //同步获取ContentSizeFitter的size Debug.Log("ContentSizeFitter size = " +" " + content.GetPreferredSize()); } } |
如下图所示,同步加载的gameobject已经可以立刻获取它的区域了
最后欢迎大家提出意见。
- 本文固定链接: https://www.xuanyusong.com/archives/4234
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!
可以自己去计算
text.rectTransform.sizeDelta = new Vector2 (text.preferredWidth,text.preferredHeight);
backGround.sizeDelta = new Vector2 (text.preferredWidth+20.0f,text.preferredHeight+20.0f);
可以用这个 Canvas.ForceUpdateCanvases();
已解决
什么方法解决的
给个demo吧 雨松老师
你好
我是unity 5.6.4p1 版本 测试上述代码不好用 log是 (0,0) 还请雨松老师 给与解答
你好
我是unity 5.6.4p1 版本 测试上述代码不好用 log是 (0,0)
感谢雨松大神 帮了大忙
这能直接导入到LuaFramework_UGUI中用吗?ContentSizeFitter fitter = GetComponent(); fitter.CallBack(delegate(Vector2 size) { Debug.Log(“size =” size); });这个直接在lua中调用,不知要不要wrap出来
这能直接导入到LuaFramework_UGUI中用吗?ContentSizeFitter fitter = GetComponent(); fitter.CallBack(delegate(Vector2 size) { Debug.Log(“size =” + size); });这个直接在lua中调用,不知要不要wrap出来
lua 里不能这样用, 可以包一层。。
等一帧是因为要刷新canvas renderer的原因?
我找了个新办法,立即可以取到。 已经更新到文章中了。