【虚幻4 / UMG】如何为网格布局(Grid Panel / Uniform Grid Panel)指定填充方向(即起始锚点)

版权声明:本文为CSDN博主「趁着头发多我想做游戏」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_37658157/article/details/124929030

问题描述

列表动态生成Item算是前端同学非常熟悉的业务了,在虚幻4的UMG中,线性布局(Horizontal Box / Vertical Box)拥有Alignment属性可以解决Item是从左往右、从右往左、从上往下或者从下往上等起始方向的指定。然而,与Unity3D里的UGUI系统不同,UE4中的网格布局(Grid Panel / Uniform Grid Panel)需要自行指定每一个Item自己的行列数(Row / Column),而且起始方向是【从左往右,从上往下】,此时需要自己通过计算来满足指定对齐方式(Alignment)的需求。


解决方案

思路:为了支持左上、左下、右上、右下四个方向作为起始锚点,其实就是计算出每一个Item自己是第几个,最后根据 x = index / col, y = index % col 计算即可( 其中x、y代表行列数,index是第几个,col是总列数)
假设本次需要填充的Item是【a,b,c,d】,数量(total)为【4】,行数(row)为【2】,列数(col)为【3】
(下面的表格中,a (0,0) = 0 代表的意思:a的行数是0,列数是0,是第0个,其余同理)

为GridSlot设置行列数详见引擎代码:…\Engine\Source\Runtime\UMG\Private\Components\GridSlot.cpp
调用其中的SetRow()和SetColumn()即可。

注意,下面的表格中,比如 a (1,2) = 3 代表的意思是:a的行数是1,列数是2,位于第3个格子中

以左上角作为起始锚点

a (0,0) = 0 b (0,1) = 1 c(0,2) = 2
d(1,0) = 3

这个情况下不需要额外的计算,因为网格布局的默认起始方向就是左上角,最终结果就是 [0,1,2,3] ( 这个数组代表被填充的数据的先后顺序)。

以右下角作为起始锚点

d(0,2) = 2
c(1,0) = 3 b (1,1) = 4 a (1,2) = 5

这个情况也很容易处理,其实就是【以左上角为起始锚点】的计算方式倒过来,最终结果就是[5,4,3,2],倒序入队即可。

以右上角作为起始锚点

c(0,0) = 0 b(0,1) = 1 a(0,2) = 2
d (1,2) = 5

这个情况比较复杂,最终的结果应该是 [2,1,0,5],要思考以左上角作为起始锚点与之之间的联系:
其实可以看得出来,【以左上角作为起始锚点】与【以右上角作为起始锚点】的区别其实就是行列数进行垂直翻转,用 a 和 c 来举例,a 的列数 = 总列数 - (c的index % c 的列数) - 1, 代入可得 a的列数 = 2,而 a的行数 = a的index / 总列数,代入得 a的行数 = 0

-- 以右上角作为起始锚点
function Func()
	local tbSlotIndex = {
    
    }
	local row = 2
	local column = 3
	local itemTotal = 4
	local totalGrid = row * column
	for i = 1, itemTotal do
        local tempIndex = i - 1
        local tempColumnIndex = column - (tempIndex % column) - 1
        local tempRowIndex = math.floor(tempIndex / column)
        local reverseIndex = (tempRowIndex * column) + tempColumnIndex
        table.insert(tbSlotIndex, reverseIndex)
    end
	return tbSlotIndex
end

以左下角作为起始锚点

d(0,0) = 0
a(1,0) = 4 b(1,1) = 5 c (1,2) = 6

这个情况与【以右上角作为起始锚点】差不多,只是与【以右下角作为起始锚点】进行垂直翻转:

-- 以左下角作为起始锚点
function Func()
	local tbSlotIndex = {
    
    }
	local row = 2
	local column = 3
	local itemTotal = 4
	local totalGrid = row * column
	local tempIndex = totalGrid - 1
	for i = itemTotal, 1, -1 do
		local tempColumnIndex = column - (tempIndex % column) - 1
		local tempRowIndex = math.floor(tempIndex / column)
		local reverseIndex = (tempRowIndex * column) + tempColumnIndex
		table.insert(tbSlotIndex, reverseIndex)
		tempIndex = tempIndex - 1
	end
	return tbSlotIndex
end

猜你喜欢

转载自blog.csdn.net/weixin_37658157/article/details/124929030
今日推荐