[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CBB7DFRPJXVCGNDV0SW0P2":3,"skill-same:01M6CBB7DFRPJXVCGNDV0SW0P2":44},{"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":17,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":21,"frontMatter":22,"refName":23,"commitSha":24,"skillDirectory":25,"forksCount":13,"repositoryHtmlUrl":26,"repositoryHomepageUrl":6,"ownerHtmlUrl":27,"ownerBlogUrl":6,"ownerDescription":28,"updatedAt":29,"install":30,"resources":43},"01M6CBB7DFRPJXVCGNDV0SW0P2","11-anim-sequence-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\u002F20-common-package\u002F11-anim-sequence-player\u002FSKILL.md",[],[18],"11 anim sequence player","2026-11-10 10:12:30",false,"# 11-anim-sequence-player\n\n## 0. 목적\n여러 AnimationClip을 순서대로 재생하고, 각 스텝별 반복\u002F속도\u002F페이드를 지원하는\nAnimator 기반 시퀀스 플레이어를 제공한다.\n\nAnimationEvent에 의존하지 않는다.\n\n---\n\n## 1. 포함 범위\n- AnimSequenceData (Serializable 데이터)\n- AnimSequencePlayer (MonoBehaviour 재생기)\n- AnimClipSelectorWindow (Editor - clip 선택 창)\n- AnimSequenceStep_Drawer (Editor - 인스펙터 UI)\n- Step 단위: clip, speed, repeat, fadeTime\n\n---\n\n## 2. 동작 규약 (Hard)\n\n### Animator 기반\n- AnimSequencePlayer는 AnimatorController 기반이며, state 재생은 Animator.Play\u002FCrossFade로 수행한다.\n- Playables(PlayableGraph\u002FMixer) 관련 코드를 사용하지 않는다.\n\n### stateName 규약\n- **기본 규약: stateName == step.Clip.name**\n- AnimatorController의 state 이름이 clip.name과 일치해야 동작한다.\n- 이 규약이 깨지면 동작 보장하지 않는다.\n\n### 완료 판정\n- AnimationEvent 사용 금지\n- 완료 판정은 AnimatorStateInfo.normalizedTime 기반(루프 count = floor(normalizedTime))\n\n### 데이터 구조\n- AnimSequenceData는 [Serializable] 데이터이며 ScriptableObject를 사용하지 않는다.\n- AnimSequenceData는 다른 컴포넌트\u002F데이터에 serialized field로 포함하는 사용을 정본으로 한다.\n- repeat == Loop 인 스텝은 자동으로 다음 스텝으로 진행하지 않는다.\n- 시퀀스 종료 시:\n  - OnComplete event + optional callback이 정확히 1회 호출된다.\n\n### Repeat>1 requires looping clip (경고)\n- AnimSequenceStep.Repeat가 One이 아닌 경우(예: Two..Ten, Loop) 해당 AnimationClip은 Looping(Loop Time) 이어야 한다.\n- Loop가 아닌 clip에 반복을 적용하면 normalizedTime이 증가하지 않아 시퀀스 진행이 block될 수 있다.\n- AnimSequencePlayer는 재생 시작 시 반복 스텝을 검사하여, loop가 아닌 clip에 반복이 걸린 경우 Warning 로그를 출력한다.\n- 경고만 출력하며 실행은 계속된다(Warn-only, 동작 차단 없음).\n\n### PlayNext 규약\n- Loop 스텝에서 다음 스텝으로 진행하려면 AnimSequencePlayer.PlayNext()를 호출한다.\n- PlayNext()는 현재 스텝이 Loop가 아니더라도 \"강제로 다음 스텝\"으로 이동한다.\n- 다음 스텝이 없으면 시퀀스를 Complete 처리한다(콜백\u002FOnComplete 1회).\n\n---\n\n## 3. Pause\u002FStop 규약 (Hard)\n- Pause(true)는 Animator.speed를 0으로 설정한다.\n- Pause(false)는 현재 스텝 속도로 복구한다.\n- Stop(invokeCallback=true)로 종료하면:\n  - callback이 있으면 1회 호출 후 내부에서 null 처리한다.\n- Stop 시 Animator.speed는 1로 복귀한다.\n\n---\n\n## 4. 페이드 규약 (Hard)\n- fadeTime \u003C= 0 이면 Animator.Play로 즉시 전환한다.\n- fadeTime > 0 이면 Animator.CrossFade로 전환한다.\n\n---\n\n## 5. Editor 선택 UI 규약 (Hard)\n- Inspector에서 AnimatorController의 animationClips 목록으로 clip을 선택 가능해야 한다.\n- Selector는 EditorWindow 기반, 클릭 즉시 적용 후 닫힘(Apply 버튼 없음)\n- ScriptableWizard 사용 금지\n\n---\n\n## 6. 금지 행동 (Hard)\n- Playables 관련 using\u002Fgraph 코드 잔존 금지\n- ScriptableWizard 사용 금지\n- AnimationClip에 AddEvent\u002FRemoveEvent 등 에셋 변경 금지\n\n---\n\n## 7. 파일 구조\n\n```\nRuntime\u002FUnity\u002FAnimSequence\u002F\n  AnimSequence.cs         # Serializable 데이터 (AnimSequenceData, AnimSequenceStep, AnimPlayCount)\n  AnimSequencePlayer.cs   # MonoBehaviour 재생기 (Animator 기반)\n\nEditor\u002FAnimSequence\u002F\n  AnimClipSelectorWindow.cs   # clip 선택 EditorWindow\n  AnimSequenceStep_Drawer.cs  # AnimSequenceStep PropertyDrawer\n```\n\n---\n\n## 8. API 요약\n\n### AnimPlayCount (enum)\n```csharp\npublic enum AnimPlayCount\n{\n    Loop = 0,\n    One = 1,\n    Two = 2,\n    \u002F\u002F ... up to Ten = 10\n}\n```\n\n### AnimSequenceStep (class)\n```csharp\n[Serializable]\npublic sealed class AnimSequenceStep\n{\n    \u002F\u002F 규약: Animator stateName == Clip.name\n    public AnimationClip Clip;\n    public float Speed = 1f;\n    public AnimPlayCount Repeat = AnimPlayCount.One;\n    public float FadeTime = 0f;\n}\n```\n\n### AnimSequenceData (Serializable)\n```csharp\n[Serializable]\npublic sealed class AnimSequenceData\n{\n    public AnimSequenceStep[] Steps;\n    public bool IsValid();\n}\n```\n\n### AnimSequencePlayer (MonoBehaviour)\n```csharp\n[RequireComponent(typeof(Animator))]\npublic sealed class AnimSequencePlayer : MonoBehaviour\n{\n    public event Action OnComplete;\n    public bool IsPlaying { get; }\n    public bool IsPaused { get; }\n    public float PlaySpeed { get; set; }\n\n    \u002F\u002F Inspector에서 기본 시퀀스 할당 가능\n    [SerializeField] private AnimSequenceData _defaultSequence;\n\n    public void PlayDefault(float playSpeed = 1f, Action onComplete = null, int startIndex = 0);\n    public void Play(AnimSequenceData sequence, float playSpeed = 1f, Action onComplete = null, int startIndex = 0);\n    public void Stop(bool invokeCallback);\n    public void Pause(bool paused);\n\n    \u002F\u002F Loop 스텝 block 상태에서 다음 스텝으로 진행 (다음이 없으면 Complete)\n    public bool PlayNext();\n}\n```\n\n### AnimClipSelectorWindow (Editor)\n```csharp\npublic sealed class AnimClipSelectorWindow : EditorWindow\n{\n    public static AnimClipSelectorWindow Open(SerializedProperty targetProperty, RuntimeAnimatorController controller);\n}\n```\n\n### AnimSequenceStep_Drawer (Editor)\n```csharp\n[CustomPropertyDrawer(typeof(AnimSequenceStep))]\npublic sealed class AnimSequenceStep_Drawer : PropertyDrawer\n{\n    \u002F\u002F Clip ObjectField + Select 버튼\n    \u002F\u002F Speed, Repeat, FadeTime 필드\n}\n```\n",{},"main","8cb5bd877a3a7004867d2f55697cb9e4ff2f1734","skills\u002Fdevian-unity\u002F20-common-package\u002F11-anim-sequence-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":31,"prompt":41,"zipAvailable":42},[32,35,38],{"tool":33,"command":34},"npx","npx skills add devwinsoft\u002Fdevian --skill 11-anim-sequence-player",{"tool":36,"command":37},"bunx","bunx skills add devwinsoft\u002Fdevian --skill 11-anim-sequence-player",{"tool":39,"command":40},"pnpm","pnpm dlx skills add devwinsoft\u002Fdevian --skill 11-anim-sequence-player","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian-unity\u002F20-common-package\u002F11-anim-sequence-player\u002FSKILL.md",true,[],[45,51,59,67,76,83],{"skillNo":46,"name":47,"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":48,"categories":49,"keywords":50,"publishedAt":19},"01M6CBX3K2JJV38ANHVGCAT8A0","devian","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002FSKILL.md",[],[47],{"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":19},"01M6CBX210BFMM8AMN770J9WY8","90-project-archive","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F90-project-archive\u002FSKILL.md",[],[57,58],"archive","90 project archive",{"skillNo":60,"name":61,"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":62,"categories":63,"keywords":64,"publishedAt":19},"01M6CBWZSGRR9R3YJZB3177667","30-env-management","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F30-env-management\u002FSKILL.md",[],[65,66],"management","30 env management",{"skillNo":68,"name":69,"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":70,"categories":71,"keywords":72,"publishedAt":19},"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",[],[73,74,75],"push","page","19 page push send",{"skillNo":77,"name":78,"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":79,"categories":80,"keywords":81,"publishedAt":19},"01M6CBWWRQ05A7604GHJKTPJTF","18-page-savedata","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F18-page-savedata\u002FSKILL.md",[],[74,82],"18 page savedata",{"skillNo":84,"name":85,"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":86,"categories":87,"keywords":88,"publishedAt":19},"01M6CBWVH4S2VF1V7B2GBTESCT","17-page-deobfuscate","https:\u002F\u002Fgithub.com\u002Fdevwinsoft\u002Fdevian\u002Fblob\u002Fmain\u002Fskills\u002Fdevian\u002F80-tools\u002F20-operation\u002F17-page-deobfuscate\u002FSKILL.md",[],[74,89],"17 page deobfuscate"]