feat(ui): 카드 hover 보간 확대 적용

- hover된 손패/보상/상점 카드를 1.5배까지 SineEaseOut 보간으로 확대

- 같은 줄의 다른 카드는 hover 카드 기준 좌우로 110px 밀어 겹침을 줄임

- hover 해제 시 같은 보간으로 scale 1.0 및 기본 위치로 복귀

- SlayDeckController.codeblock 산출물을 생성기로 재생성

검증:

- node --check tools/deck/gen-slaydeck.mjs

- node --test tools/balance/sim-balance.test.mjs tools/map/rogue-map.test.mjs
This commit is contained in:
2026-06-14 02:50:47 +09:00
parent 4d3f6fc0af
commit d3ae6c1c62
2 changed files with 66 additions and 8 deletions

View File

@@ -1416,7 +1416,7 @@
"Name": "hover"
}
],
"Code": "local e = _EntityService:GetEntityByPath(path)\nif e == nil or e.UITransformComponent == nil then\n\treturn\nend\nif hover == true and e.Enable == true then\n\te.UITransformComponent.UIScale = Vector3(1.12, 1.12, 1)\nelse\n\te.UITransformComponent.UIScale = Vector3(1, 1, 1)\nend",
"Code": "local prefix = \"\"\nlocal count = 0\nlocal xs = {}\nlocal baseY = 0\nlocal hoverIndex = 0\nlocal push = 110\nif string.find(path, \"/ui/DefaultGroup/CardHand/Card\") == 1 then\n\tprefix = \"/ui/DefaultGroup/CardHand/Card\"\n\tcount = 5\n\txs = { -400, -200, 0, 200, 400 }\n\tbaseY = 0\n\thoverIndex = tonumber(string.match(path, \"Card(%d+)\")) or 0\nelseif string.find(path, \"/ui/DefaultGroup/RewardHud/Reward\") == 1 then\n\tprefix = \"/ui/DefaultGroup/RewardHud/Reward\"\n\tcount = 3\n\txs = { -300, 0, 300 }\n\tbaseY = 0\n\thoverIndex = tonumber(string.match(path, \"Reward(%d+)\")) or 0\nelseif string.find(path, \"/ui/DefaultGroup/ShopHud/Card\") == 1 then\n\tprefix = \"/ui/DefaultGroup/ShopHud/Card\"\n\tcount = 3\n\txs = { -300, 0, 300 }\n\tbaseY = 20\n\thoverIndex = tonumber(string.match(path, \"Card(%d+)\")) or 0\nend\nif count <= 0 then\n\treturn\nend\nlocal items = {}\nfor i = 1, count do\n\tlocal e = _EntityService:GetEntityByPath(prefix .. tostring(i))\n\tif e ~= nil and e.UITransformComponent ~= nil then\n\t\tlocal tr = e.UITransformComponent\n\t\tlocal tx = xs[i]\n\t\tlocal ty = baseY\n\t\tlocal sc = 1\n\t\tif hover == true and hoverIndex > 0 then\n\t\t\tif i == hoverIndex and e.Enable == true then\n\t\t\t\tsc = 1.5\n\t\t\telseif i < hoverIndex then\n\t\t\t\ttx = tx - push\n\t\t\telseif i > hoverIndex then\n\t\t\t\ttx = tx + push\n\t\t\tend\n\t\tend\n\t\ttable.insert(items, { tr = tr, sx = tr.anchoredPosition.x, sy = tr.anchoredPosition.y, ss = tr.UIScale.x, tx = tx, ty = ty, ts = sc })\n\tend\nend\nlocal elapsed = 0\nlocal duration = 0.12\nlocal eventId = 0\neventId = _TimerService:SetTimerRepeat(function()\n\telapsed = elapsed + 1 / 60\n\tlocal t = math.min(elapsed / duration, 1)\n\tlocal eased = _TweenLogic:Ease(0, 1, 1, EaseType.SineEaseOut, t)\n\tfor i = 1, #items do\n\t\tlocal it = items[i]\n\t\tlocal x = it.sx + (it.tx - it.sx) * eased\n\t\tlocal y = it.sy + (it.ty - it.sy) * eased\n\t\tlocal s = it.ss + (it.ts - it.ss) * eased\n\t\tit.tr.anchoredPosition = Vector2(x, y)\n\t\tit.tr.UIScale = Vector3(s, s, 1)\n\tend\n\tif t >= 1 then\n\t\t_TimerService:ClearTimer(eventId)\n\tend\nend, 1 / 60)",
"Scope": 2,
"ExecSpace": 6,
"Attributes": [],

View File

@@ -3259,15 +3259,73 @@ end`, [
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'base' },
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' },
]),
method('SetCardHover', `local e = _EntityService:GetEntityByPath(path)
if e == nil or e.UITransformComponent == nil then
method('SetCardHover', `local prefix = ""
local count = 0
local xs = {}
local baseY = 0
local hoverIndex = 0
local push = 110
if string.find(path, "/ui/DefaultGroup/CardHand/Card") == 1 then
prefix = "/ui/DefaultGroup/CardHand/Card"
count = 5
xs = { ${CARD_XS.join(', ')} }
baseY = 0
hoverIndex = tonumber(string.match(path, "Card(%d+)")) or 0
elseif string.find(path, "/ui/DefaultGroup/RewardHud/Reward") == 1 then
prefix = "/ui/DefaultGroup/RewardHud/Reward"
count = 3
xs = { -300, 0, 300 }
baseY = 0
hoverIndex = tonumber(string.match(path, "Reward(%d+)")) or 0
elseif string.find(path, "/ui/DefaultGroup/ShopHud/Card") == 1 then
prefix = "/ui/DefaultGroup/ShopHud/Card"
count = 3
xs = { -300, 0, 300 }
baseY = 20
hoverIndex = tonumber(string.match(path, "Card(%d+)")) or 0
end
if count <= 0 then
return
end
if hover == true and e.Enable == true then
e.UITransformComponent.UIScale = Vector3(1.12, 1.12, 1)
else
e.UITransformComponent.UIScale = Vector3(1, 1, 1)
end`, [
local items = {}
for i = 1, count do
local e = _EntityService:GetEntityByPath(prefix .. tostring(i))
if e ~= nil and e.UITransformComponent ~= nil then
local tr = e.UITransformComponent
local tx = xs[i]
local ty = baseY
local sc = 1
if hover == true and hoverIndex > 0 then
if i == hoverIndex and e.Enable == true then
sc = 1.5
elseif i < hoverIndex then
tx = tx - push
elseif i > hoverIndex then
tx = tx + push
end
end
table.insert(items, { tr = tr, sx = tr.anchoredPosition.x, sy = tr.anchoredPosition.y, ss = tr.UIScale.x, tx = tx, ty = ty, ts = sc })
end
end
local elapsed = 0
local duration = 0.12
local eventId = 0
eventId = _TimerService:SetTimerRepeat(function()
elapsed = elapsed + 1 / 60
local t = math.min(elapsed / duration, 1)
local eased = _TweenLogic:Ease(0, 1, 1, EaseType.SineEaseOut, t)
for i = 1, #items do
local it = items[i]
local x = it.sx + (it.tx - it.sx) * eased
local y = it.sy + (it.ty - it.sy) * eased
local s = it.ss + (it.ts - it.ss) * eased
it.tr.anchoredPosition = Vector2(x, y)
it.tr.UIScale = Vector3(s, s, 1)
end
if t >= 1 then
_TimerService:ClearTimer(eventId)
end
end, 1 / 60)`, [
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' },
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'hover' },
]),