[task] | distill [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | ```lua -- 핵심 로직: 방향 전환 및 등반 처리 local curLookAt = playerControllerComponent.FixedLookAt if curLookAt == 0 then curLookAt = moveDir.x end self:FlipTo(curLookAt) if not isDead then -- 수직 입력(threshold 초과) 시 등반 동작 if math.abs(moveDir.y) > moveVStartValue then if moveDir.y > moveVStar [original] | lerComponent:ActionJump(horizontalInput) end end end -- Update character facing direction local curLookAt = playerControllerComponent.FixedLookAt if curLookAt == 0 then curLookAt = moveDir.x end self:FlipTo(curLookAt) -- Handle ladder [chunk_id] | Guides:1403:13
[task] | extract_knowledge [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | # 커스텀 PlayerController 컴포넌트 초기화 ## 1. 개념 설명 메이플스토리 월드의 기본 `PlayerController` 동작을 대체하거나 확장하기 위해 커스텀 스크립트를 사용하는 경우, 컴포넌트 초기화 로직을 직접 구현해야 합니다. 이 과정은 클라이언트 환경(`[client only]`)에서 수행되며, 로컬 플레이어(`LocalPlayer`)에게만 적용됩니다. 커스텀 초기화는 `UseCustomScript` 플래그가 `true`일 때만 진행되며, 다음과 같은 5가지 핵심 메서드로 구성됩니다. 1. **`On [original] | 컴포넌트를 초기화할 수 있도록 아래 5가지 메소드를 추가하고, 아래와 같이 작성합니다. `UseCustomScript`가 `false`이면 초기화하지 않으며, LocalPlayer인 경우에만 키 매핑, Hold 액션 설정, 이벤트 핸들러 등록, 컴포넌트 캐싱을 수행합니다. - `OnBeginPlay()`: 컴포넌트 초기화의 진입점으로 키, 핸들러, 컴포넌트를 설정하고 StateComponent의 HitEventHandler를 재정의합니다. - `InitKeys()`: 액션 키와 상호작용 키의 기본 매핑을 등록합니다. - `Init [chunk_id] | Guides:1403:2
[task] | diverse_qa [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | 질문: `OnKeyHold` 메서드가 실행되는 공간은 어디인가요? 답변: `OnKeyHold` 메서드는 `[client only]` 어노테이션이 붙어 있어 클라이언트 공간에서만 실행됩니다. 질문: `OnKeyHold` 함수 내에서 `self:CanControl()`이 false일 때 어떤 일이 발생하나요? 답변: `self:CanControl()`이 false라면 함수가 즉시 반환(return)되어 이후의 로직은 실행되지 않습니다. 질문: `self.EnableInHierarchy`가 false인 경우 `OnKeyHold` 함수 [original] | [client only] void OnKeyHold(KeyHoldEvent evt) { -- Handle key hold events: update hold action state (for keys pressed without keyDown) if not self:CanControl() then return end if not self.EnableInHierarchy then return end local key = evt.key loc [chunk_id] | Guides:1403:10
[task] | knowledge_list [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | 제시된 원문(코드 스니펫)에 포함된 정보만 바탕으로 핵심 사실을 추출한 목록입니다. 원문에 없는 API나 사실은 추측하지 않았습니다. 1. `playerControllerComponent` 객체의 `ActionJump` 메서드를 호출할 때 `horizontalInput` 값을 매개변수로 전달한다. 2. `playerControllerComponent` 객체의 `FixedLookAt` 프로퍼티 값을 로컬 변수 `curLookAt`에 할당하여 현재 바라보기 방향을 확인한다. 3. `curLookAt` 값이 0인 경우, `moveDir [original] | lerComponent:ActionJump(horizontalInput) end end end -- Update character facing direction local curLookAt = playerControllerComponent.FixedLookAt if curLookAt == 0 then curLookAt = moveDir.x end self:FlipTo(curLookAt) -- Handle ladder [chunk_id] | Guides:1403:13
[task] | extract_knowledge [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | # 커스텀 PlayerController: Action 및 Condition 관리 기존 컴포넌트와 동일한 인터페이스를 사용하여 키보드 입력(Action)과 실행 조건(Condition)을 관리하기 위한 메서드들을 구현합니다. 이 절에서는 `ActionKeys`(키-액션 매핑 테이블)와 `ActionConditions`(액션-조건 함수 목록 테이블)을 기반으로 하는 로직을 다룹니다. ## 개념 설명 커스텀 컨트롤러는 다음과 같은 핵심 개념을 기반으로 동작합니다. 1. **Action (액션)**: 게임 내에서 수행할 동작(예 [original] | 기존 컴포넌트와 동일한 인터페이스의 Action, Condition을 관리할 수 있는 메소드를 만들어봅시다. - `GetActionName()`: 키에 매핑된 액션 이름을 반환합니다. - `SetActionKey()`: 키에 액션 이름을 매핑합니다. - `RemoveActionKey()`: 특정 키의 매핑을 제거합니다. - `RemoveAllActionKeyByActionName()`: 특정 액션에 매핑된 모든 키를 제거합니다. - `AddCondition()`: 액션 실행 조건 함수를 추가합니다. - `RemoveAllCondi [chunk_id] | Guides:1403:5
[task] | diverse_qa [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | 질문: 위 코드에서 `playerControllerComponent:ActionJump(horizontalInput)`이 호출되는 조건은 무엇인가요? 답변: 문서에 제시된 코드 스니펫만으로는 `ActionJump`가 호출되는 정확한 조건(예: 점프 입력 감지 로직)이 명시되어 있지 않습니다. 질문: 캐릭터의 바라보는 방향(`curLookAt`)이 0일 때, 최종적으로 `FlipTo`에 전달되는 값은 무엇인가요? 답변: `playerControllerComponent.FixedLookAt`의 값이 0인 경우, `moveDir.x` [original] | lerComponent:ActionJump(horizontalInput) end end end -- Update character facing direction local curLookAt = playerControllerComponent.FixedLookAt if curLookAt == 0 then curLookAt = moveDir.x end self:FlipTo(curLookAt) -- Handle ladder [chunk_id] | Guides:1403:13
[task] | distill [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | #### UpdateControl 보조 메소드 `UpdateControl`을 지원하기 위해 다음 5가지 메소드를 구현합니다. - **`ResetControl()`**: 컨트롤 초기화 및 상태를 `IDLE`로 변경. - **`ResetKeys()`**: 입력 상태(`InputKeys`, `PressedKeys`) 및 축 값 초기화. - **`SetInputAxis()`**: 활성화된 키를 기반으로 수평/수직 입력 축 계산. - **`GetDirectionValue()`**: 입력 값과 임계값 비교를 통한 방향 값 반환. - **` [original] | #### UpdateControl 보조 메소드 UpdateControl을 보조하기 위해 아래 5가지 메소드를 추가하고, 아래와 같이 작성합니다. - `ResetControl()`: 컨트롤을 초기화하고 상태를 IDLE로 변경합니다. - `ResetKeys()`: 입력 상태를 초기화합니다. - `SetInputAxis()`: 활성화된 키를 기반으로 수평/수직 입력 축을 계산합니다. - `GetDirectionValue()`: 입력 값과 임계값을 비교하여 방향 값을 반환합니다. - `FlipTo()`: 캐릭터의 방향을 설정합니다. [chunk_id] | Guides:1403:14
[task] | extract_knowledge [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | # 커스텀 PlayerController 입력 처리 로직 ## 1. 개념 설명 커스텀 `PlayerController`는 `InputService`의 키 입력 이벤트를 수신하여 플레이어의 액션을 수행하고 입력 상태를 관리합니다. `InitEventHandlers()` 메서드에서 이벤트 핸들러를 등록하고, 아래 다섯 가지 핵심 메서드를 통해 입력 주기를 제어합니다. * **`OnKeyDown()`**: 키를 누르는 순간(`KeyDownEvent`)에 트리거됩니다. 액션 실행과 입력 상태 갱신을 담당합니다. * **`OnK [original] | `InitEventHandlers()`에서 `InputService`의 키 입력 이벤트에 연결된 핸들러 메소드를 아래와 같이 작성합니다. - `OnKeyDown()`: 키를 누르는 순간의 입력을 처리하여 액션을 실행하고 입력 상태를 갱신합니다. - `SendActionEventToServer()`: 커스텀 액션 이벤트를 서버로 전송합니다. - `OnKeyUp()`: 키에서 손을 떼는 순간의 입력을 처리하여 관련 상태를 해제합니다. - `OnKeyHold()`: 키를 누르고 있는 동안의 입력 상태를 갱신합니다. - `BlockInp [chunk_id] | Guides:1403:8
[task] | wikipedia [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | `UpdateControl()`은 입력된 키를 기반으로 플레이어 컨트롤을 업데이트하는 핵심 메서드입니다. 이 메서드는 이동 방향 계산, 앉기 및 점프 액션 처리, 캐릭터 방향 업데이트, 그리고 사다리 등반 처리를 수행합니다. 아래 코드는 `UpdateControl()` 메서드의 구현 예시입니다. ```lua Method: [client only] void UpdateControl(number delta) { -- Main control update: handles movement, actions, and state tra [original] | `UpdateControl()`은 입력된 키를 기반으로 플레이어 컨트롤을 업데이트하는 핵심 메소드입니다. 이동 방향 계산, 앉기/점프 액션 처리, 캐릭터 방향 업데이트, 사다리 등반 처리를 수행합니다. ```lua Method: [client only] void UpdateControl(number delta) { -- Main control update: handles movement, actions, and state transitions if not self:CanControl() then sel [chunk_id] | Guides:1403:12
[task] | knowledge_list [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | 제시된 문서에 포함된 코드 블록과 메서드 시그니처를 바탕으로 추출한 핵심 사실 목록입니다. 1. `GetDirectionValue` 메서드는 `[client only]` 실행 공간에서 동작하며, `number` 타입의 `value`와 `threshold`를 매개변수로 받아 `number` 타입을 반환한다. 2. `GetDirectionValue` 메서드는 `value`가 `threshold`보다 크면 `1`을, `value`가 `-threshold`보다 작으면 `-1`을, 그 외에는 `0`을 반환한다. 3. `FlipTo` 메서드 [original] | [client only] number GetDirectionValue(number value, number threshold) { if value > threshold then return 1 elseif value < -threshold then return -1 else return 0 end } [client only] void FlipTo(number lookAt) { if math.almostequal(lookAt, 0) then [chunk_id] | Guides:1403:15
[task] | knowledge_list [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | 제공된 문서 내용만 바탕으로 `UpdateControl`을 보조하는 메소드들의 핵심 사실을 정리한 목록입니다. * `ResetControl` 메서드는 `[client only]` 실행 공간에서 `void` 반환 타입으로 정의되며, 내부적으로 `ResetKeys`를 호출한 후 `self.StateComponent`의 `CurrentStateName`이 "IDLE"이 아닌 경우 `ChangeState("IDLE")`를 호출하여 컨트롤 초기화와 상태 변경을 수행합니다. * `ResetKeys` 메서드는 `[client only] [original] | #### UpdateControl 보조 메소드 UpdateControl을 보조하기 위해 아래 5가지 메소드를 추가하고, 아래와 같이 작성합니다. - `ResetControl()`: 컨트롤을 초기화하고 상태를 IDLE로 변경합니다. - `ResetKeys()`: 입력 상태를 초기화합니다. - `SetInputAxis()`: 활성화된 키를 기반으로 수평/수직 입력 축을 계산합니다. - `GetDirectionValue()`: 입력 값과 임계값을 비교하여 방향 값을 반환합니다. - `FlipTo()`: 캐릭터의 방향을 설정합니다. [chunk_id] | Guides:1403:14
[task] | distill [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | ### 커스텀 PlayerController 로직 아래 메서드는 클라이언트에서만 실행되며, 입력값의 방향을 결정하고 캐릭터의 좌우 방향(`LookDirectionX`)을 갱신합니다. **1. 방향 값 정규화** 입력값(`value`)이 임계값(`threshold`)을 초과할 때만 1, -1, 0 중 하나의 값을 반환하여 미세한 입력 노이즈를 제거합니다. ```lua [client only] number GetDirectionValue(number value, number threshold) { if value > thr [original] | [client only] number GetDirectionValue(number value, number threshold) { if value > threshold then return 1 elseif value < -threshold then return -1 else return 0 end } [client only] void FlipTo(number lookAt) { if math.almostequal(lookAt, 0) then [chunk_id] | Guides:1403:15
[task] | diverse_qa [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | 질문: `UpdateControl()` 메서드는 주로 어떤 역할을 수행합니까? 답변: `UpdateControl()`은 입력된 키를 기반으로 플레이어 컨트롤을 업데이트하는 핵심 메소드로, 이동 방향 계산, 앉기/점프 액션 처리, 캐릭터 방향 업데이트, 사다리 등반 처리를 수행합니다. 질문: `UpdateControl()` 메서드가 실행되기 전에 `self:CanControl()`이 false를 반환하는 경우 어떤 일이 발생합니까? 답변: `self:CanControl()`이 false인 경우 `self:ResetControl()` [original] | `UpdateControl()`은 입력된 키를 기반으로 플레이어 컨트롤을 업데이트하는 핵심 메소드입니다. 이동 방향 계산, 앉기/점프 액션 처리, 캐릭터 방향 업데이트, 사다리 등반 처리를 수행합니다. ```lua Method: [client only] void UpdateControl(number delta) { -- Main control update: handles movement, actions, and state transitions if not self:CanControl() then sel [chunk_id] | Guides:1403:12
[task] | extract_knowledge [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | # 커스텀 PlayerController의 입력 처리 및 상태 관리 본 절에서는 mLua 환경에서 커스텀 `PlayerController` 컴포넌트가 클라이언트 입력을 처리하고, 서버에 액션을 전달하며, 특정 상태(웅크림 등)를 해제하는 로직을 구현하는 방법을 다룹니다. ## 1. 개념 설명 커스텀 플레이어 컨트롤러는 기본적으로 `InputKeys`와 `ActionKeys` 테이블을 통해 키보드 입력을 매핑합니다. * **액션 이벤트 전송**: 클라이언트에서 액션이 발생하면 `CustomPlayerActionEvent`를 [original] | = self.Entity actionEvent.ActionName = actionName self.Entity:SendEvent(actionEvent) self:SendActionEventToServer(actionEvent) end } [server] void SendActionEventToServer(CustomPlayerActionEvent evt) { self.Entity:SendEvent(evt) } [client only] void OnKeyUp [chunk_id] | Guides:1403:9
[task] | wikipedia [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | 제시된 원문은 `PlayerController` 컴포넌트 내부의 특정 로직(이동 방향 처리, 사다리/그네 오르기 처리)에 대한 코드 조각 일부입니다. 해당 코드는 `Update` 또는 유사한 주기적 호출 메서드 내에서 실행되며, 캐릭터의 이동 입력에 따라 점프, 방향 전환, 그리고 등반 동작을 제어합니다. 먼저, 캐릭터의 이동 방향과 점프 로직이 처리된 직후, 캐릭터가 바라보는 방향을 업데이트합니다. `playerControllerComponent`의 `FixedLookAt` 속성을 확인하여 현재 고정된 시선 각도(`curLook [original] | lerComponent:ActionJump(horizontalInput) end end end -- Update character facing direction local curLookAt = playerControllerComponent.FixedLookAt if curLookAt == 0 then curLookAt = moveDir.x end self:FlipTo(curLookAt) -- Handle ladder [chunk_id] | Guides:1403:13
[task] | diverse_qa [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | 질문: `GetDirectionValue` 메서드는 어떤 실행 공간에서 작동하나요? 답변: `GetDirectionValue` 메서드는 `[client only]` 실행 공간에서 작동합니다. 질문: `GetDirectionValue` 함수에서 `value`가 `threshold`보다 크고 `-threshold`보다 작지 않은 경우 반환되는 값은 무엇인가요? 답변: `value`가 `threshold`보다 큰 경우 함수는 1을 반환합니다. 질문: `GetDirectionValue` 함수에서 `value`가 `threshold`와 [original] | [client only] number GetDirectionValue(number value, number threshold) { if value > threshold then return 1 elseif value < -threshold then return -1 else return 0 end } [client only] void FlipTo(number lookAt) { if math.almostequal(lookAt, 0) then [chunk_id] | Guides:1403:15
[task] | distill [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | ```lua [client only] number GetVelocity() { local mapComponent = self.MapComponent if mapComponent == nil then return 0 end local timeMapMode = mapComponent.TileMapMode if timeMapMode == TileMapMode.MapleTile then local comp = self.RigidbodyComponent if c [original] | [client only] number GetVelocity() { local mapComponent = self.MapComponent if mapComponent == nil then return 0 end local timeMapMode = mapComponent.TileMapMode if timeMapMode == TileMapMode.MapleTile then local comp = self.RigidbodyComponent if comp [chunk_id] | Guides:1403:17
[task] | wikipedia [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | # 커스텀 PlayerController: 키 홀드 처리 및 입력 차단 메이플스토리 월드의 커스텀 `PlayerController` 컴포넌트는 클라이언트 사이드에서 키 입력을 처리하며, 특히 `KeyHoldEvent`를 통해 유지되는 키 입력의 상태를 관리하고 조건에 따라 입력을 차단하는 로직을 포함합니다. 이 섹션에서는 `OnKeyHold` 이벤트 핸들러와 `BlockInputKey` 메서드의 동작 방식을 상세히 설명합니다. ## OnKeyHold 이벤트 핸들러 `OnKeyHold` 메서드는 `[client only]` 실행 [original] | [client only] void OnKeyHold(KeyHoldEvent evt) { -- Handle key hold events: update hold action state (for keys pressed without keyDown) if not self:CanControl() then return end if not self.EnableInHierarchy then return end local key = evt.key loc [chunk_id] | Guides:1403:10
[task] | wikipedia [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | # UpdateControl 보조 메소드 `UpdateControl` 메소드의 기능을 보조하기 위해 `ResetControl`, `ResetKeys`, `SetInputAxis`, `GetDirectionValue`, `FlipTo` 총 5가지 메소드를 추가해야 합니다. 각 메소드의 역할은 다음과 같습니다. 첫째, `ResetControl()`은 컨트롤을 초기화하고 캐릭터의 상태를 `IDLE`로 변경하는 역할을 합니다. 둘째, `ResetKeys()`는 현재 입력 상태를 초기화합니다. 셋째, `SetInputAxis()`는 활성 [original] | #### UpdateControl 보조 메소드 UpdateControl을 보조하기 위해 아래 5가지 메소드를 추가하고, 아래와 같이 작성합니다. - `ResetControl()`: 컨트롤을 초기화하고 상태를 IDLE로 변경합니다. - `ResetKeys()`: 입력 상태를 초기화합니다. - `SetInputAxis()`: 활성화된 키를 기반으로 수평/수직 입력 축을 계산합니다. - `GetDirectionValue()`: 입력 값과 임계값을 비교하여 방향 값을 반환합니다. - `FlipTo()`: 캐릭터의 방향을 설정합니다. [chunk_id] | Guides:1403:14
[task] | knowledge_list [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | 제시된 문서와 코드 블록에 포함된 정보만을 기반으로 핵심 사실을 추출하여 목록으로 정리합니다. * `GetVelocity` 메서드는 `[client only]` 실행 공간에서 동작하며, 반환 타입은 `number`입니다. * 메서드 실행 시 먼저 `self.MapComponent`를 확인하여 `nil`인 경우 즉시 `0`을 반환합니다. * `self.MapComponent.TileMapMode` 값이 `TileMapMode.MapleTile`일 때, `self.RigidbodyComponent`가 `nil`이 아니면 ` [original] | [client only] number GetVelocity() { local mapComponent = self.MapComponent if mapComponent == nil then return 0 end local timeMapMode = mapComponent.TileMapMode if timeMapMode == TileMapMode.MapleTile then local comp = self.RigidbodyComponent if comp [chunk_id] | Guides:1403:17
[task] | diverse_qa [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | 질문: `UpdateControl` 메소드를 보조하기 위해 추가된 5가지 메소드의 이름은 무엇인가요? 답변: `ResetControl()`, `ResetKeys()`, `SetInputAxis()`, `GetDirectionValue()`, `FlipTo()`입니다. 질문: `ResetControl()` 메소드의 주요 역할은 무엇인가요? 답변: 컨트롤을 초기화하고 캐릭터의 상태를 IDLE로 변경하는 것입니다. 질문: `ResetControl()` 메소드에서 상태가 IDLE로 변경되는 조건은 무엇인가요? 답변: `self.Stat [original] | #### UpdateControl 보조 메소드 UpdateControl을 보조하기 위해 아래 5가지 메소드를 추가하고, 아래와 같이 작성합니다. - `ResetControl()`: 컨트롤을 초기화하고 상태를 IDLE로 변경합니다. - `ResetKeys()`: 입력 상태를 초기화합니다. - `SetInputAxis()`: 활성화된 키를 기반으로 수평/수직 입력 축을 계산합니다. - `GetDirectionValue()`: 입력 값과 임계값을 비교하여 방향 값을 반환합니다. - `FlipTo()`: 캐릭터의 방향을 설정합니다. [chunk_id] | Guides:1403:14
[task] | wikipedia [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | **게임 로직 커스텀 PlayerController 만들기** 이 문서는 메이플스토리 월드의 스크립트 언어 mLua를 사용하여 커스텀 PlayerController 컴포넌트의 방향 처리 로직을 구현하는 방법을 다룹니다. 제공된 예제는 클라이언트 환경에서만 실행되는 두 가지 메서드로 구성되어 있으며, 입력 값의 사각지대(threshold) 처리와 캐릭터의 바라보는 방향(Flip)을 제어하는 역할을 수행합니다. **GetDirectionValue 메서드** `GetDirectionValue`는 `[client only]` 실행 공 [original] | [client only] number GetDirectionValue(number value, number threshold) { if value > threshold then return 1 elseif value < -threshold then return -1 else return 0 end } [client only] void FlipTo(number lookAt) { if math.almostequal(lookAt, 0) then [chunk_id] | Guides:1403:15
[task] | distill [title] | 커스텀 폰트 [category] | Guides [rephrased] | **Font Group**은 언어별 폰트를 묶어 클라이언트 언어 설정에 맞춰 자동 적용하는 기능입니다. ### 설정 항목 - **새로고침**: 추가한 폰트 로드 - **Font Group Name**: 그룹 편집 탭 - **삭제**: 폰트 그룹 삭제 - **언어 선택**: 적용할 언어 지정 - **Font Name**: `Font` 탭에서 저장한 폰트 이름 입력 - **Add Font Group**: 새로운 폰트 그룹 추가 ### 폰트 적용 등록한 폰트는 아래 컴포넌트의 `Font` 프로퍼티에서 선택하여 사용할 수 있습니다. [original] | **Font Group** 탭에서는 언어별로 서로 다른 폰트를 하나의 그룹으로 묶어, 클라이언트 언어 설정에 맞는 폰트가 자동으로 적용되도록 만들 수 있습니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/178403001449300fda3d4d8254d438f113d670d408f8a.png "2") | 번호 | 이름 | 설명 | | --- | --- | --- | | ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/stor [chunk_id] | Guides:1404:1
[task] | extract_knowledge [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | # 게임 로직 커스텀 PlayerController 만들기: `UpdateControl()` ## 1. 개념 설명 `UpdateControl()`은 입력된 키를 기반으로 플레이어 컨트롤을 업데이트하는 핵심 메소드입니다. 이 메소드는 이동 방향 계산, 앉기(Crouch)/점프 액션 처리, 캐릭터 방향 업데이트, 사다리 등반 처리를 수행합니다. ## 2. API 사용법 * **실행 공간**: `[client only]` * **매개변수**: `delta` (number) - 프레임 간 시간 차이 * **주요 접근 객체** [original] | `UpdateControl()`은 입력된 키를 기반으로 플레이어 컨트롤을 업데이트하는 핵심 메소드입니다. 이동 방향 계산, 앉기/점프 액션 처리, 캐릭터 방향 업데이트, 사다리 등반 처리를 수행합니다. ```lua Method: [client only] void UpdateControl(number delta) { -- Main control update: handles movement, actions, and state transitions if not self:CanControl() then sel [chunk_id] | Guides:1403:12
[task] | wikipedia [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | ## 상태 전환 메소드 플레이어의 지면 상태와 이동 속도를 기반으로 게임 상태를 전환하기 위해 `CheckGroundMoveOrFall`, `IsOnGround`, `GetVelocity` 세 가지 메소드를 구현합니다. `CheckGroundMoveOrFall` 메소드는 플레이어의 지면 유무와 이동 속도를 확인하여 상태를 변경합니다. 구체적으로, 플레이어가 지면에 있고 이동 중이라면 상태는 `MOVE`로 전환됩니다. 반대로, 지면에 없으며 현재 상태가 `IDLE`라면 상태는 `FALL`로 전환됩니다. 이 과정에서 `ATTACK` [original] | #### 상태 전환 메소드 플레이어의 지면 상태와 이동 속도를 확인하여 상태를 전환하도록 아래 3가지 메소드를 추가하고, 아래와 같이 작성합니다. - `CheckGroundMoveOrFall()`: 지면 여부와 이동 속도를 확인하여 상태를 전환합니다. 지면에 있고 이동 중이면 MOVE 상태로, 지면에 없고 IDLE 상태면 FALL 상태로 전환합니다. - `IsOnGround()`: 현재 맵 모드에 맞는 물리 컴포넌트를 통해 플레이어가 지면에 있는지 확인합니다. - `GetVelocity()`: 현재 맵 모드에 맞는 물리 컴포넌트 [chunk_id] | Guides:1403:16
[task] | wikipedia [title] | 커스텀 폰트 [category] | Guides [rephrased] | **UI 커스텀 폰트** 메이플스토리 월드(MapleStory Worlds)의 **Font Group** 탭에서는 언어별로 상이한 폰트를 하나의 그룹으로 묶어 관리할 수 있습니다. 이 기능을 통해 클라이언트의 언어 설정에 부합하는 폰트가 자동으로 적용됩니다. Font Group 탭의 주요 기능과 항목은 다음과 같습니다. 먼저, **새로고침** 버튼을 통해 추가한 폰트를 다시 불러올 수 있습니다. **Font Group Name**은 해당 그룹을 편집하는 탭을 지칭합니다. **삭제** 기능은 추가한 폰트를 월드에서 사용하지 않도록 [original] | **Font Group** 탭에서는 언어별로 서로 다른 폰트를 하나의 그룹으로 묶어, 클라이언트 언어 설정에 맞는 폰트가 자동으로 적용되도록 만들 수 있습니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/178403001449300fda3d4d8254d438f113d670d408f8a.png "2") | 번호 | 이름 | 설명 | | --- | --- | --- | | ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/stor [chunk_id] | Guides:1404:1
[task] | diverse_qa [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | 질문: `CheckGroundMoveOrFall` 메소드는 어떤 조건에서 플레이어를 "MOVE" 상태로 전환하나요? 답변: 플레이어의 이동 속도(velocity)가 0.00001(epsilon)보다 크고, 현재 상태가 "ATTACK"가 아닐 때, 또는 `AlwaysMovingState` 속성이 true일 때 "MOVE" 상태로 전환합니다. 질문: `CheckGroundMoveOrFall` 메소드에서 "FALL" 상태로 전환되는 조건은 무엇인가요? 답변: 플레이어가 지면에 있지 않고(`IsOnGround()`가 false), 현재 [original] | #### 상태 전환 메소드 플레이어의 지면 상태와 이동 속도를 확인하여 상태를 전환하도록 아래 3가지 메소드를 추가하고, 아래와 같이 작성합니다. - `CheckGroundMoveOrFall()`: 지면 여부와 이동 속도를 확인하여 상태를 전환합니다. 지면에 있고 이동 중이면 MOVE 상태로, 지면에 없고 IDLE 상태면 FALL 상태로 전환합니다. - `IsOnGround()`: 현재 맵 모드에 맞는 물리 컴포넌트를 통해 플레이어가 지면에 있는지 확인합니다. - `GetVelocity()`: 현재 맵 모드에 맞는 물리 컴포넌트 [chunk_id] | Guides:1403:16
[task] | wikipedia [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | # GetVelocity `GetVelocity`는 클라이언트에서 실행되는(`[client only]`) 메서드로, 현재 엔티티의 이동 속도의 제곱 크기를 계산하여 반환합니다. 이 메서드는 맵의 타일 모드에 따라 물리 컴포넌트를 다르게 참조하므로, 다양한 맵 환경에서 일관된 속도 값을 제공합니다. 메서드는 먼저 `self.MapComponent`를 확인합니다. 해당 컴포넌트가 `nil`인 경우, 즉시 `0`을 반환하여 오류를 방지합니다. `MapComponent`가 존재하면 `TileMapMode` 속성을 읽어 현재 맵의 유형을 [original] | [client only] number GetVelocity() { local mapComponent = self.MapComponent if mapComponent == nil then return 0 end local timeMapMode = mapComponent.TileMapMode if timeMapMode == TileMapMode.MapleTile then local comp = self.RigidbodyComponent if comp [chunk_id] | Guides:1403:17
[task] | distill [title] | 커스텀 PlayerController 만들기 [category] | Guides [rephrased] | ### 상태 전환 메소드 플레이어의 지면 상태와 이동 속도를 기반으로 `MOVE`, `FALL` 상태로 전환하는 3가지 메소드를 정의합니다. **1. `CheckGroundMoveOrFall()`** - **동작 규칙**: - 지면(`IsOnGround()`)에 있고, 이동 속도(`GetVelocity()`)가 `0.00001` 이상이며, 현재 상태가 `ATTACK`이 아니면 `MOVE` 상태로 전환합니다. - 지면(`IsOnGround()`)에 있고, `AlwaysMovingState`가 `true`이면 `MOV [original] | #### 상태 전환 메소드 플레이어의 지면 상태와 이동 속도를 확인하여 상태를 전환하도록 아래 3가지 메소드를 추가하고, 아래와 같이 작성합니다. - `CheckGroundMoveOrFall()`: 지면 여부와 이동 속도를 확인하여 상태를 전환합니다. 지면에 있고 이동 중이면 MOVE 상태로, 지면에 없고 IDLE 상태면 FALL 상태로 전환합니다. - `IsOnGround()`: 현재 맵 모드에 맞는 물리 컴포넌트를 통해 플레이어가 지면에 있는지 확인합니다. - `GetVelocity()`: 현재 맵 모드에 맞는 물리 컴포넌트 [chunk_id] | Guides:1403:16
[task] | distill [title] | 커스텀 폰트 [category] | Guides [rephrased] | # UI 커스텀 폰트 월드 텍스트에 커스텀 폰트를 적용하기 위해 리소스 스토리지에 폰트를 등록하고, 월드에 폰트 그룹을 설정합니다. ## 1. 리소스 스토리지에 폰트 등록 1. **Resource Storage**에서 `font` 폴더/카테고리에 폰트 파일을 업로드합니다. 2. 메타 정보 확인 후 세부정보에서 **이름, 설명, 폰트 렌더 모드, 폰트 샘플링 사이즈**를 설정합니다. **규칙 및 주의사항** * **이름 제약**: 알파벳(대/소문자), `_`, `-`, 숫자만 허용됩니다. * **렌더 모드**: `SDF [original] | 제작한 월드의 분위기와 어울리는 폰트를 추가해 월드의 텍스트에 적용할 수 있습니다. 폰트를 리소스 스토리지에 등록하고, 커스텀 폰트 그룹창에서 월드에 사용할 폰트를 묶는 방법에 대해 알아봅시다. ## 리소스 스토리지에 폰트 추가 월드에서 폰트를 사용하기 위해서는 먼저 리소스 스토리지에 폰트를 등록해야 합니다. 폰트 등록 시 이름은 **알파벳 대소문자, `_`, `-`, 숫자** 조합만 가능합니다. 리소스 스토리지에 업로드할 폰트의 저작권과 사용 범위를 반드시 확인한 후 등록하길 권장합니다. 폰트 파일 등록 방법은 아래와 같습니 [chunk_id] | Guides:1404:0