{"id":49858996,"url":"https://github.com/stellar-f0x/unity-input-layer","last_synced_at":"2026-05-14T21:02:11.613Z","repository":{"id":321163485,"uuid":"1083261745","full_name":"Stellar-F0X/Unity-Input-Layer","owner":"Stellar-F0X","description":"유니티의 입력 시스템을 레이어 구조로 다뤄 입력을 처리","archived":false,"fork":false,"pushed_at":"2026-01-22T21:34:25.000Z","size":88,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-23T14:23:34.789Z","etag":null,"topics":["input","input-layer","input-system","layer","unity"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Stellar-F0X.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-25T17:01:12.000Z","updated_at":"2026-01-22T21:34:28.000Z","dependencies_parsed_at":"2025-10-28T07:09:59.648Z","dependency_job_id":"07a893f3-f43f-44df-8407-b52f172de501","html_url":"https://github.com/Stellar-F0X/Unity-Input-Layer","commit_stats":null,"previous_names":["stellar-f0x/unity-input-layer"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Stellar-F0X/Unity-Input-Layer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stellar-F0X%2FUnity-Input-Layer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stellar-F0X%2FUnity-Input-Layer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stellar-F0X%2FUnity-Input-Layer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stellar-F0X%2FUnity-Input-Layer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Stellar-F0X","download_url":"https://codeload.github.com/Stellar-F0X/Unity-Input-Layer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Stellar-F0X%2FUnity-Input-Layer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33043249,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["input","input-layer","input-system","layer","unity"],"created_at":"2026-05-14T21:02:08.183Z","updated_at":"2026-05-14T21:02:11.608Z","avatar_url":"https://github.com/Stellar-F0X.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Unity Input Layer System\n\nUnity의 Input System을 레이어 기반으로 관리할 수 있는 확장 시스템입니다. \u003cbr\u003e\n스택 구조를 통해 UI, 게임플레이, 메뉴 등 다양한 컨텍스트에서 입력 우선순위를 자동으로 관리합니다.\n\n## 주요 기능\n\n- **스택 기반 입력 관리**: 레이어를 스택에 푸시/팝하여 입력 컨텍스트를 자동 전환\n- **우선순위 자동 처리**: 최상단 레이어만 입력을 받아 충돌 방지\n- **중앙화된 제어**: InputManager를 통한 전역 입력 흐름 관리\n- **컴포넌트 기반**: InputReceiver로 입력 로직을 컴포넌트화\n\n## 요구사항\n\n- Unity 2019.1 이상\n- Unity Input System 패키지\n\n## 설치\n\n### Package Manager를 통한 설치\n\n1. Unity 에디터에서 `Window \u003e Package Manager` 열기\n2. `+` 버튼 클릭 → `Add package from git URL...` 선택\n3. 다음 URL 입력:\n\n```\nhttps://github.com/Stellar-F0X/Unity-Input-Layer.git\n```\n\n### manifest.json을 통한 설치\n\n`Packages/manifest.json` 파일에 다음 줄을 추가:\n\n```json\n{\n  \"dependencies\": {\n    \"com.stellarfox.input-layer\": \"https://github.com/Stellar-F0X/Unity-Input-Layer.git\"\n  }\n}\n```\n\n## 빠른 시작\n\n### 1. Input Action Asset 설정\n\nProject Settings \u003e Input System Package에서 Input-wide로 Input Action Asset을 설정합니다.\n\n### 2. InputManager 설정\n\n씬에 InputManager가 자동으로 생성되거나, 직접 GameObject에 추가합니다.\n\n추가된 InputManager 컴포넌트의 Inspector에서 Root로 삼을 레이어를 설정합니다.\n\n```csharp\n[SerializeField] private InputLayerName _rootLayer; // \"Player\" 등\n```\n\n**주의 Root 레이어는 런타임 중에 없앨 수 없습니다.**\n\n### 3. 기본 사용법\n\n```csharp\nusing InputLayer.Runtime;\nusing UnityEngine;\n\npublic class GameManager : MonoBehaviour\n{\n    [SerializeField] private InputLayerController controller;\n\n    private void Start()\n    {\n        controller.PushInputLayer(\"UI\"); // UI 레이어 추가\n    }\n\n    private void OnMenuClosed()\n    {\n        controller.PopInputLayer(); // UI 레이어 제거 (아래 있는 레이어로 자동 복귀)\n    }\n}\n```\n\n## 핵심 컴포넌트\n\n### InputLayerController\n\n레이어 스택을 조작하고 이벤트를 구독할 수 있는 컴포넌트입니다. \nGameObject에 추가하여 사용합니다.\n\n**메서드**\n\n```csharp\n[SerializeField] private InputLayerController controller;\n\n// 레이어 푸시\ncontroller.PushInputLayer(\"UI\");\n\n// 레이어 팝\ncontroller.PopInputLayer();\n\n// 루트 제외 모든 레이어 제거\ncontroller.PopAllInputLayersExpectRoot();\n\n// 현재 최상단 레이어 확인\nInputLayer currentLayer = controller.peekInputLayer;\n```\n\n**이벤트**\n\n```csharp\npublic class SomeClass : MonoBehaviour\n{\n    [SerializeField] private InputLayerController controller;\n\n    private void Start()\n    {\n        controller.onPushedInputLayer += OnLayerPushed;\n        controller.onPoppedInputLayer += OnLayerPopped;\n    }\n\n    private void OnLayerPushed(InputLayer layer)\n    {\n        Debug.Log($\"레이어 추가됨: {layer.mapName}\");\n    }\n\n    private void OnLayerPopped(InputLayer layer)\n    {\n        Debug.Log($\"레이어 제거됨: {layer.mapName}\");\n    }\n\n    private void OnDestroy()\n    {\n        controller.onPushedInputLayer -= OnLayerPushed;\n        controller.onPoppedInputLayer -= OnLayerPopped;\n    }\n}\n```\n\n### InputReceiver\n\n특정 레이어의 입력을 받는 컴포넌트입니다. GameObject에 추가하고 Inspector에서 레이어를 지정합니다.\n\n**설정**\n\n```csharp\npublic class PlayerController : MonoBehaviour\n{\n    [SerializeField] private InputReceiver inputReceiver; // Inspector에서 레이어 지정 필요\n}\n```\n\n**입력 읽기 메서드**\n\n```csharp\nprivate void Update()\n{\n    // 버튼이 이번 프레임에 눌렸는지\n    if (inputReceiver.ReadButtonDown(\"Jump\"))\n    {\n        Jump();\n    }\n\n    // 버튼이 현재 눌려있는지\n    if (inputReceiver.ReadButton(\"Fire\"))\n    {\n        Shoot();\n    }\n\n    // 버튼이 이번 프레임에 떼어졌는지\n    if (inputReceiver.ReadButtonUp(\"Aim\"))\n    {\n        StopAiming();\n    }\n\n    // 값 읽기 (Vector2, float 등)\n    if (inputReceiver.ReadInput(\"Move\", out Vector2 movement))\n    {\n        Move(movement);\n    }\n}\n```\n\n**콜백 등록**\n\n```csharp\nprivate void Start()\n{\n    // 콜백 등록 - 레이어가 활성화되지 않아도 콜백은 동작합니다\n    _inputReceiver.RegisterInputAction(\"Jump\", InputCallback.Performed, OnJumpPerformed);\n}\n\nprivate void OnJumpPerformed(InputAction.CallbackContext context)\n{\n    Debug.Log(\"Jump performed!\");\n}\n\nprivate void OnDestroy()\n{\n    // 콜백 제거 필수\n    _inputReceiver.UnregisterInputAction(\"Jump\", InputCallback.Performed);\n}\n```\n\n**주의사항**\n\n- `ReadInput`, `ReadButton`, `ReadButtonDown`, `ReadButtonUp`은 해당 InputReceiver의 레이어가 **최상단 레이어가 아니면** 항상 false를 반환합니다\n- 콜백(`RegisterInputAction`)은 레이어 활성화 여부와 무관하게 동작합니다\n- InputReceiver는 지정된 레이어의 Input Action에만 접근 가능합니다\n\n### InputLayerName\n\n인스펙터에서 Input Action Map을 선택할 수 있는 직렬화 가능한 타입입니다.\n\n```csharp\n[SerializeField] \nprivate InputLayerName _playerLayer;\n\nprivate void Start()\n{\n    Debug.Log(_playerLayer.name); // \"Player\"\n    Debug.Log(_playerLayer.id);   // Guid\n}\n```\n\n### InputCallback\n\n입력 콜백 타입을 지정하는 플래그 열거형입니다.\n\n```csharp\n// 단일 콜백\nInputCallback.Started\nInputCallback.Canceled\nInputCallback.Performed\n\n// 복합 콜백\nInputCallback.All // Started | Canceled | Performed\nInputCallback.Started | InputCallback.Performed\n```\n\n## 사용 예시\n\n### UI 메뉴 시스템\n\n```csharp\npublic class PauseMenu : MonoBehaviour\n{\n    public InputLayerController controller;\n    \n    private void OnEnable()\n    {\n        controller.PushInputLayer(\"UI\"); // 메뉴가 열리면 UI 레이어 활성화\n    }\n\n    private void OnDisable()\n    {   \n        controller.PopInputLayer(); // 메뉴가 닫히면 이전 레이어로 복귀\n    }\n}\n```\n\n### 대화 시스템\n\n```csharp\npublic class DialogueSystem : MonoBehaviour\n{\n    public InputReceiver dialogueInput;\n    public InputLayerController controller;\n\n    private void StartDialogue()\n    {\n        controller.PushInputLayer(\"Dialogue\"); // 대화 시작시, Dialogue 레이어만 활성화\n        \n        dialogueInput.RegisterInputAction(\"Submit\", InputCallback.Performed, OnDialogueAdvance);\n    }\n\n    private void EndDialogue()\n    {\n        dialogueInput.UnregisterInputAction(\"Submit\", InputCallback.Performed);\n        \n        controller.PopInputLayer(); // 대화 종료시, Dialogue 레이어를 제거하고 기존 레이어 활성화.\n    }\n\n    private void OnDialogueAdvance(InputAction.CallbackContext ctx)\n    {\n        // 다음 대화로 진행\n    }\n}\n```\n\n### 인벤토리 시스템\n\n```csharp\npublic class InventoryUI : MonoBehaviour\n{\n    public InputLayerController controller;\n    \n    private void Open()\n    {\n        controller.PushInputLayer(\"Inventory\"); // 플레이어 이동 입력이 자동으로 차단됨\n    }\n\n    private void Close()\n    {\n        controller.PopInputLayer(); // 플레이어 이동 입력 재개\n    }\n}\n```\n\n## 디버그 모드\n\nInputManager의 인스펙터에서 Debug 옵션을 활성화하면 게임 화면 좌측 상단에 현재 레이어 스택이 표시됩니다.\n\n- **노란색**: Root 레이어\n- **초록색**: 현재 활성 레이어 (최상단)\n- **흰색**: 비활성 레이어\n\n## 아키텍처\n\n### 레이어 스택 구조\n\n스택의 최상위에 위치한 입력 레이어만 입력이 활성화됩니다. \n\n\n루트 입력 레이어는 제거하거나 실행 도중에 변경이 불가능합니다. \n\n```\n┌─────────────────┐\n│   UI Layer      │ ← 현재 활성 (입력 받음)\n├─────────────────┤\n│  Player Layer   │ ← 비활성\n├─────────────────┤\n│  Root Layer     │ ← 절대 제거 불가\n└─────────────────┘\n```\n\n### 입력 우선순위\n\nInputReceiver의 입력 읽기 메서드(`ReadInput`, `ReadButton` 등)는 다음 우선순위에 따라 동작합니다:\n\n1. **입력 차단 확인**: `inputBlock`이 true면 모든 입력 차단\n2. **레이어 매칭 확인**: InputReceiver의 레이어가 현재 최상단 레이어(`peekInputLayer`)와 일치하지 않으면 입력 무시\n3. **입력 처리**: 최상단 레이어의 InputReceiver만 입력을 읽을 수 있음\n\n**중요**: 콜백(`RegisterInputAction`)은 이 우선순위 규칙을 따르지 않고, 해당 Input Action이 활성화되어 있으면 항상 호출됩니다.\n\n## 라이선스\n\nMIT License\n\n## 기여\n\n이슈와 풀 리퀘스트를 환영합니다!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstellar-f0x%2Funity-input-layer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstellar-f0x%2Funity-input-layer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstellar-f0x%2Funity-input-layer/lists"}