[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CBG5FJ04MW9MBQ6ECSJC6X":3,"skill-same:01M6CBG5FJ04MW9MBQ6ECSJC6X":50},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":25,"linkOnly":26,"markdownContent":27,"markdownBody":27,"frontMatter":28,"refName":29,"commitSha":30,"skillDirectory":31,"forksCount":13,"repositoryHtmlUrl":32,"repositoryHomepageUrl":6,"ownerHtmlUrl":33,"ownerBlogUrl":6,"ownerDescription":34,"updatedAt":35,"install":36,"resources":49},"01M6CBG5FJ04MW9MBQ6ECSJC6X","14-ui-transition-player",null,"devwinsoft\u002Fdevian","devwinsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F22570160?v=4","01M6C6RR8W05NH8NPKQNCE3Q72","maoshy","01M6C6RRDJ5TJJCZXRTY801YDH",0,"MIT","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian-unity\u002F23-ui-package\u002F22-ui-tween-system\u002F14-ui-transition-player\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[23,24],"ui","14 ui transition player","2026-11-10 10:12:30",false,"# 14-ui-transition-player\n\nStatus: ACTIVE\nAppliesTo: v2\nType: Runtime Specification\n\n## Purpose\n\n`UITransitionPlayer`는 compiled transition result를 실제 UI 대상에 적용하는 executor다.\n\n## Target Code Path\n\n```text\nframework-cs\u002Fupm\u002Fcom.devian.foundation\u002FSamples~\u002FUIPackage\u002FRuntime\u002FTween\u002FUITransitionPlayer.cs\n```\n\n## Target References\n\n- same-GameObject `RectTransform` (required)\n- same-GameObject `CanvasGroup` (optional)\n- same-GameObject `LayoutElement` (optional)\n\n## Minimum API\n\n```csharp\npublic sealed class UITransitionPlayer : MonoBehaviour\n{\n    public UITweenHandle Play(UITransitionPreset preset, Action onComplete = null);\n    public UITweenHandle Play(UITransitionPresetAsset asset, Action onComplete = null);\n    public UITweenHandle Play(UI_TRANSITION_PRESET_ID id, Action onComplete = null);\n    public UITweenHandle Play(UITweenSequence sequence, Action onComplete = null);\n    public void Cancel();\n}\n```\n\n## Rules\n\n- player는 main transition 채널 1개만 가진다\n- 새 `Play(...)` 호출 시 기존 main transition은 cancel된다\n- `RectTransform`는 `[RequireComponent(typeof(RectTransform))]`로 같은 GameObject에 필수다\n- alpha는 같은 GameObject의 `CanvasGroup`에 적용한다\n- anchoredPosition은 같은 GameObject의 `RectTransform`에 적용한다\n- scale은 같은 GameObject의 `transform.localScale`에 적용한다\n- preferred size는 같은 GameObject의 `LayoutElement.preferredWidth\u002FpreferredHeight`에 적용한다\n- `Play(...)`는 preset 또는 sequence를 `UICompiledTransitionData`로 compile한 뒤 runner에 위임한다\n- play 시작 시 `CaptureSnapshot()`으로 alpha \u002F scale과 anchoredPosition baseline을 캡처한다\n- 매 프레임 `UITransitionFrameResult`만 적용한다\n- move 결과는 player가 보관한 anchoredPosition baseline 기준 offset으로 계산된다\n- preferred size 결과는 absolute `preferredWidth\u002FpreferredHeight` 값으로 적용된다\n- `CanvasGroup`가 없고 preset이 alpha를 요구하면 alpha 채널만 경고 후 skip 한다\n- `LayoutElement`가 없고 preset이 preferred size를 요구하면 preferred size 채널만 경고 후 skip 한다\n- `Play(UI_TRANSITION_PRESET_ID id)`는 editor play mode에서 raw preset asset을 우선 resolve한다\n- bundle build\u002Fruntime에서는 cached `UITransitionPresetAsset`을 사용한다\n- bundle\u002Fruntime 경로를 쓰기 전에는 preset asset bundle이 선로드되어 있어야 한다\n- 현재 기본 bootstrap은 `MobileApplication.onLoadCompletedAsync()`에서 `ui` label의 `UITransitionPresetAsset`을 preload한다\n- `Reset\u002FAwake\u002FOnValidate`에서 same-GameObject target 참조를 보정한다\n- `Reset\u002FAwake\u002FOnValidate`에서 anchoredPosition baseline도 갱신한다\n- 외부 코드가 baseline 자체를 바꿨다면 `RefreshBaseline()`으로 수동 동기화할 수 있다\n- `OnDestroy()`에서는 현재 main handle을 cancel한다\n- player는 preset 의미를 소유하지 않는다. 어떤 preset을 재생할지는 owner가 결정한다\n\n## Attachment Guidance\n\n- `UITransitionPlayer`는 `LayoutRoot`보다 내부 `VisualRoot`에 붙이는 것을 우선한다\n- `UITransitionPlayer`는 tween 대상과 같은 GameObject에 붙인다\n- layout과 함께 폭\u002F높이를 바꾸려면 `LayoutElement.preferredWidth\u002FpreferredHeight` 채널을 사용한다\n- `UIBasePanel`은 base `Show()` \u002F `Hide()` 또는 concrete panel API에서 player를 호출할 수 있다\n- `UIBaseContainer`는 non-layout visual root에만 tween을 적용한다\n- `UIBaseFrame`가 기본 적용 지점이다\n- item add \u002F reward gain \u002F badge update 같은 game event에서는 owner component가 manual `Play(...)`를 직접 호출한다\n- pooled object는 despawn 전 `Cancel()`을 호출하는 경로를 가져야 한다\n- `UIScrollContainer` virtualized item의 hide tween에는 사용하지 않는다\n\n## Responsibility Boundary\n\n- `UIBasePanel.Show()` \u002F `UIBasePanel.Hide()`, `Container` \u002F `Frame`의 명시적 API, 또는 game event handler가 transition 타이밍을 결정한다\n- 어떤 preset을 쓸지는 `UITransitionPlayer`가 아니라 owner(`UIToastFrame`, concrete panel 등)가 결정한다\n- `UITransitionPlayer`는 실행만 담당한다\n- queue, state, duplicate 판단은 player 책임이 아니다\n",{},"main","8cb5bd877a3a7004867d2f55697cb9e4ff2f1734","skills\u002Fdevian-unity\u002F23-ui-package\u002F22-ui-tween-system\u002F14-ui-transition-player","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian","https:\u002F\u002Fgithub.com\u002Fdevwinsoft","Kim Hyong Joon","2026-04-12 18:44:10",{"source":7,"skillName":5,"commands":37,"prompt":47,"zipAvailable":48},[38,41,44],{"tool":39,"command":40},"npx","npx skills add devwinsoft\u002Fdevian --skill 14-ui-transition-player",{"tool":42,"command":43},"bunx","bunx skills add devwinsoft\u002Fdevian --skill 14-ui-transition-player",{"tool":45,"command":46},"pnpm","pnpm dlx skills add devwinsoft\u002Fdevian --skill 14-ui-transition-player","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian-unity\u002F23-ui-package\u002F22-ui-tween-system\u002F14-ui-transition-player\u002FSKILL.md",true,[],[51,57,65,73,82,89],{"skillNo":52,"name":53,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":54,"categories":55,"keywords":56,"publishedAt":25},"01M6CBX3K2JJV38ANHVGCAT8A0","devian","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002FSKILL.md",[],[53],{"skillNo":58,"name":59,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":60,"categories":61,"keywords":62,"publishedAt":25},"01M6CBX210BFMM8AMN770J9WY8","90-project-archive","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F90-project-archive\u002FSKILL.md",[],[63,64],"archive","90 project archive",{"skillNo":66,"name":67,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":25},"01M6CBWZSGRR9R3YJZB3177667","30-env-management","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F30-env-management\u002FSKILL.md",[],[71,72],"management","30 env management",{"skillNo":74,"name":75,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":78,"publishedAt":25},"01M6CBWYD3TGWBQV7V35551THF","19-page-push-send","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F19-page-push-send\u002FSKILL.md",[],[79,80,81],"push","page","19 page push send",{"skillNo":83,"name":84,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":25},"01M6CBWWRQ05A7604GHJKTPJTF","18-page-savedata","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F18-page-savedata\u002FSKILL.md",[],[80,88],"18 page savedata",{"skillNo":90,"name":91,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":94,"publishedAt":25},"01M6CBWVH4S2VF1V7B2GBTESCT","17-page-deobfuscate","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F17-page-deobfuscate\u002FSKILL.md",[],[80,95],"17 page deobfuscate"]