# 모바일 조작 처리

## 개요

ContextActionService는 게임플레이 중 키보드, 마우스, 터치 등 다양한 입력 방식을 효과적으로 처리하고, 상황에 맞는 인터페이스를 손쉽게 구현할 수 있도록 도와줍니다. 이를 통해 플레이어 입력을 간편하게 관리하고, 게임 내 Context에 따라 유연하게 동작을 할당하거나 해제할 수 있습니다.

## 특징

* **키보드, 마우스, 터치** 등 여러 입력 장치를 동일한 방식으로 처리할 수 있습니다.
* PC 환경의 **Studio**와 **모바일** 플랫폼에서 호환되며, 입력 처리를 간소화합니다.
* 메뉴 화면, 게임플레이 등 특정 상황에 따라 필요한 입력만 활성화할 수 있습니다.
* **UserInputState**를 통해 입력 상태를 구분해 세부적인 동작을 설정할 수 있습니다.

## 사용 방법

### 1. 액션 생성하기

LocalScript에서 **BindAction 함수**를 이용해 액션을 생성할 수 있습니다. 액션을 생성할 때, 액션의 이름과 TouchButton 생성 여부, PC에서 사용할 입력 키를 지정할 수 있습니다.

```lua
local ContextActionService = game:GetService("ContextActionService")

local ActionName = "JumpAction"
local IsCreateTouchButton = true
local KeyCode = Enum.KeyCode.F

local function OnAction(actionName, inputState, inputObject)
    if inputState == Enum.UserInputState.Begin then
        print(actionName .. " triggered!")
    end
end
ContextActionService:BindAction(ActionName, OnAction, IsCreateTouchButton, KeyCode)
```

<figure><img src="/files/w2n3jXpHGIWzHE2KFQQR" alt=""><figcaption></figcaption></figure>

생성한 액션은 다음과 같이 글자나 버튼의 이미지, 위치를 설정할 수 있습니다.

```lua
ContextActionService:SetTitle(ActionName, "TEST")
ContextActionService:SetImage(ActionName, "ovdrassetid://1234")
ContextActionService:SetPosition(ActionName, UDim2.new(0.5, 0, 0.8, 0))
```

<figure><img src="/files/d93pRXbjbOj5ARNMlXga" alt=""><figcaption></figcaption></figure>

### 2. 액션 해제하기

상점에 입장했을 때 공격 버튼을 비활성화하는 등, 특정 액션이 필요하지 않을 때 **UnbindAction 함수**를 이용해 비활성화할 수 있습니다.

```lua
local ContextActionService = game:GetService("ContextActionService")
local ActionName = "JumpAction"

ContextActionService:UnbindAction(ActionName)
```

### 3. 입력 상태별 처리

**UserInputState**를 이용하여 입력 시작, 입력 중, 입력 종료와 같은 상태별 처리를 구현할 수 있습니다.

```lua
local function OnAction(actionName, inputState, inputObject)
    if inputState == Enum.UserInputState.Begin then
        print("Begin!")
        
    elseif inputState == Enum.UserInputState.Change then
        print("Change!")
        
    elseif inputState == Enum.UserInputState.End then
        print("End!")
        
    elseif inputState == Enum.UserInputState.Cancel then
        print("Cancel!")
    end
end
ContextActionService:BindAction(ActionName, OnAction, IsCreateTouchButton, KeyCode)
```

<table><thead><tr><th width="152">Type</th><th>설명</th></tr></thead><tbody><tr><td>Begin</td><td>입력이 시작될 때</td></tr><tr><td>Change</td><td>입력이 지속 중일 때</td></tr><tr><td>End</td><td>입력이 종료될 때</td></tr><tr><td>Cancel</td><td>입력이 중단될 때 (예 : 입력점이 버튼 영역에서 이탈)</td></tr></tbody></table>

### 4. 특정 액션 가져오기

**GetButton 함수**로 특정 버튼을 가져올 수 있습니다.

```lua
local ActionButton = ContextActionService:GetButton(ActionName)
```

### 5. 생성된 액션 모두 가져오기

**GetAllBoundActionInfo 함수**로 모든 버튼을 가져올 수 있습니다.

```lua
local ContextActionService = game:GetService("ContextActionService")
local AllActions = ContextActionService:GetAllBoundActionInfo()

for actionName, actionInfo in pairs(AllActions) do
    print("Action Name : ", actionName)
    print("Input Types : ", actionInfo.InputTypes) 
end
```

## 기본 입력 처리

### 모바일 조이스틱, 점프 버튼 표시 제어

**SetCoreGuiEnabled 함수**로 모바일의 조이스틱과 점프 버튼의 표시 여부를 설정할 수 있습니다.

```lua
local StarterGui = game:GetService("StarterGui")

StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Joystick, false)
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.JumpButton, false)
```

### 모바일 화면 터치 감지

**TouchStarted, TouchMoved, TouchEnded** 이벤트를 사용하면 각각 터치 시작, 위치 변화, 종료에 대한 처리를 수행할 수 있습니다. 이 이벤트들의 연결 함수에는 input과 \_gameProcessed가 인자로 전달됩니다.

* input : 터치 입력 시점, 상태, 위치 등 관련 정보가 구성된 객체
* \_gameProcessed : 입력 위치가 아래에 나열된 UI 요소들과 겹치는 경우, true를 반환합니다.
  * 채팅창과 같은 네이티브 UI
  * 조이스틱, 점프 버튼과 같은 기본 조작 버튼
  * Active가 true인 GUI 버튼
  * BindAction으로 바인딩된 액션

```lua
local UserInputService = game:GetService("UserInputService")
local ActiveTouches = {} -- 동시에 발생하는 여러 터치 입력을 개별적으로 처리하기 위한 테이블

local function OnScreenTouchStart(input, _gameProcessed)
    local keyCode = input.KeyCode    
    if keyCode == Enum.KeyCode.Joystick then
        return
    end
    
    table.insert(ActiveTouches, input)
    
    local inputState = input.UserInputState -- Begin
    local inputType = input.UserInputType   -- Touch
    local delta = input.Delta
    local pos = input.Position    

    -- Do Something
end
UserInputService.TouchStarted:Connect(OnScreenTouchStart)

local function OnScreenTouchMove(input, _gameProcessed)
    local keyCode = input.KeyCode    
    if keyCode == Enum.KeyCode.Joystick then
        return
    end
        
    for i = 1, #ActiveTouches do
        -- 여러 터치 입력 중에서 현재 입력(input)에 해당하는 터치를 탐색
        if input == ActiveTouches[i] then
            local inputState = input.UserInputState -- Change
            local inputType = input.UserInputType   -- Touch
            local delta = input.Delta
            local pos = input.Position            
            
            -- Do Something
        end
    end
end
UserInputService.TouchMoved:Connect(OnScreenTouchMove)

local function OnScreenTouchEnd(input, _gameProcessed)
    local keyCode = input.KeyCode    
    if keyCode == Enum.KeyCode.Joystick then
        return
    end

    local i
    for j = 1, #ActiveTouches do
        if input == ActiveTouches[j] then
            i = j
            break        
        end
    end
    
    local inputState = input.UserInputState -- End
    local inputType = input.UserInputType   -- Touch
    local delta = input.Delta
    local pos = input.Position 

    -- Do Something

    table.remove(ActiveTouches, i)
end
UserInputService.TouchEnded:Connect(OnScreenTouchEnd)
```

### 모바일 조이스틱 입력 감지

```lua
local UserInputService = game:GetService("UserInputService")

local function OnJoystickStart(input, _gameProcessed)
    local keyCode = input.KeyCode
    if keyCode ~= Enum.KeyCode.Joystick then
        return
    end
    
    local inputState = input.UserInputState -- Begin
    local inputType = input.UserInputType   -- Touch     
    local delta = input.Delta
    local pos = input.Position
    
    -- Do Something
end
UserInputService.TouchStarted:Connect(OnJoystickStart)

local function OnJoystickMove(input, _gameProcessed)   
    local keyCode = input.KeyCode
    if keyCode ~= Enum.KeyCode.Joystick then
        return
    end
    
    local inputState = input.UserInputState -- Change
    local inputType = input.UserInputType   -- Touch 
    local delta = input.Delta
    local pos = input.Position
    
    -- Do Something
end
UserInputService.TouchMoved:Connect(OnJoystickMove)

local function OnJoystickEnd(input, _gameProcessed)   
    local keyCode = input.KeyCode    
    if keyCode ~= Enum.KeyCode.Joystick then
        return
    end
    
    local inputState = input.UserInputState -- Change
    local inputType = input.UserInputType   -- Touch 
    local delta = input.Delta
    local pos = input.Position
    
    -- Do Something
end
UserInputService.TouchEnded:Connect(OnJoystickEnd)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.overdare.com/korean/manual/script-manual/input-and-controls/contextactionservice.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
