版权声明:本文为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 |
这个情况与【以右上角作为起始锚点】差不多,只是与【以右下角作为起始锚点】进行垂直翻转:
![](/qrcode.jpg)
-- 以左下角作为起始锚点
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