[Unity]发包前遇到的坑之GridLayoutGroup

news/2025/1/11 21:34:54 标签: unity, ugui, GridLayoutGroup, LayoutGroup, 世界坐标

发包前禁用了UI上面一个调试页面A后,发现无法正确获取某一个用了LayoutGroup>GridLayoutGroup组件的所有子物体的世界坐标

一顿研究之后发现,在Start的时候想要正确获取其坐标,需要强制刷新一次布局,方法如下:
 

UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(this.GetComponent<RectTransform>());

至于为什么启用了调试页面A之后就能正确获取子物体的世界坐标,我猜是因为启用调试页面A后,整个预制体的Start时间变长,或者页面计算布局耗时更久,导致可以正确获取坐标。(有待验证)。

以下是在demo里总结的一些经验,非常容易理解,直接贴代码了。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestLayoutGroup : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // 游戏第一帧无法直接获取LayoutGroup>GridLayoutGroup组件下子物体的世界坐标
        Debug.Log("LayoutGroup: " + this.transform.position);

        foreach (Transform transform in this.transform)
        {
            // 这里会连续打印多个相同的坐标
            Debug.Log(transform.name + ": " + transform.position);
        }


        // 方法1:获取坐标前强制刷新布局ForceRebuildLayoutImmediate
        // 这是一个静态方法,用于立即重建指定 RectTransform 上的布局,确保所有布局组件
        // (如 HorizontalLayoutGroup、VerticalLayoutGroupLayoutGroup>GridLayoutGroup)更新它们的子元素。
        /*        UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(this.GetComponent<RectTransform>());

                Debug.Log("LayoutGroup: " + this.transform.position);

                foreach (Transform transform in this.transform)
                {
                    Debug.Log(transform.name + ": " + transform.position);
                }*/


        // 方法2:在当前帧结束后再获取子物体坐标
        //StartCoroutine(IEGetChildPosition());

    }

    IEnumerator IEGetChildPosition()
    {
        Debug.Log("LayoutGroup: " + this.transform.position);
        yield return new WaitForEndOfFrame();
        foreach (Transform transform in this.transform)
        {
            Debug.Log(transform.name + ": " + transform.position);
        }
    }
}

写到这里,发现yield return new WaitForEndOfFrame()未必靠谱,假如帧时间过长,这么处理可能未必可以正确获取到想要的坐标。

所以建议在获取坐标前先使用ForceRebuildLayoutImmediate强制刷新布局。


http://www.niftyadmin.cn/n/5820227.html

相关文章

ffmpeg7.0 aac转pcm

#pragma once #define __STDC_CONSTANT_MACROS #define _CRT_SECURE_NO_WARNINGSextern "C" { #include "libavcodec/avcodec.h" }//缓冲区大小&#xff08;缓存5帧数据&#xff09; #define AUDIO_INBUF_SIZE 40960 /*name depthu8 8s16 …

Euler 21.10安装oracle 19.22单机安装

1.虚拟机安装 服务器的名称和hosts文件名称要一样 hostnamectl set-hostname hfdb95 && bash 查看系统版本&#xff1a; uname -a cat /etc/redhat-release 2.IP地址配置 TYPEEthernet PROXY_METHODnone BROWSER_ONLYno BOOTPROTOnone DEFROUTEyes IPV4_FAILURE_…

ffmpeg 常用命令 案例

更详细请参考ffmpeg手册&#xff0c;下载ffmpegrelease版后在doc中就有&#xff0c;主页面。 ffmpeg主要命令的详细参考&#xff1a; ffmpeg Documentation # Main-options -version -formats -demuxers -protocols -muxers -filters -devices -codecs -sample_fmts -decode…

w~自动驾驶~合集16

我自己的原文哦~ https://blog.51cto.com/whaosoft/12765612 #SIMPL 用于自动驾驶的简单高效的多智能体运动预测基准 原标题&#xff1a;SIMPL: A Simple and Efficient Multi-agent Motion Prediction Baseline for Autonomous Driving 论文链接&#xff1a;https://ar…

mysql message from server: “Too many connections“

背景 新部署完的数据库&#xff0c;一些基本参数未设置时&#xff0c;应用启动后&#xff0c;日志报错如下 2025-01-09 09:54:40.162 [TID: N/A] [main] ERROR c.a.m.studio.runner.ExtraDDLRunner -加载应用动态数据源失败 com.zaxxer.hikari.pool.HikariPool$PoolInitializ…

如何使用Scala和Selenium爬取知乎视频并保存到本地

一、环境准备 在开始之前&#xff0c;我们需要确保已经安装了以下环境和工具&#xff1a; Java开发环境&#xff1a;Selenium是基于Java开发的&#xff0c;因此需要先安装Java开发环境&#xff0c;可以从Oracle官网下载并安装JDK 11或更高版本。Scala开发环境&#xff1a;可以…

Qt C++读写NFC标签NDEF网址URI

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.1d292c1biFgjSs&ftt&id615391857885 #include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> #include "QLibrary" …

计算机网络(三)——局域网和广域网

一、局域网 特点&#xff1a;覆盖较小的地理范围&#xff1b;具有较低的时延和误码率&#xff1b;使用双绞线、同轴电缆、光纤传输&#xff0c;传输效率高&#xff1b;局域网内各节点之间采用以帧为单位的数据传输&#xff1b;支持单播、广播和多播&#xff08;单播指点对点通信…