ContentSizeFitter使用Preferred Size来设置RectTransform不能立即生效,必须要等一帧,也可以利用OnRectTransformDimensionsChange的回调方法。
但是这么做还是很恶心,最好还是能同步的计算出它的区域,一般我们可能会横向纵向的嵌套Layout。
主要就是 LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform); 这一句。 如果不想用下面的脚本。 也可以在取RectTransofrm的size之前加上这一句
unity版本:5.3.5
不废话了直接上代码啦。
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。
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的原因?
我找了个新办法,立即可以取到。 已经更新到文章中了。