← 목록

mLua · Nemotron SDG 질문-응답 (SFT)

총 21,567개 · 페이지 377/719
🔀 랜덤
불러오는 중…

[task] | code [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | 엔티티가 삭제될 때 OnEndPlay에서 "Cleaning up..."을 로그로 출력하고, 이후 호출되는 OnDestroy에서 "Entity Destroyed"를 로그로 출력하여 호출 순서를 확인하는 스크립트를 작성해줘. [answer] | 엔티티가 제거될 때 `OnEndPlay`와 `OnDestroy` 함수가 호출되는 순서를 확인하기 위한 스크립트입니다. `OnEndPlay`가 먼저 호출되어 "Cleaning up..."을 출력하고, 그 이후에 `OnDestroy`가 호출되어 "Entity Destroyed"를 출력하도록 구현했습니다. ```lua Method: [server only] void OnEndPlay() { log("Cleaning up...") } [server only] void OnDestroy() { log("Entity Dest [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `OnBeginPlay` 함수 호출 이후, 프레임마다 호출되는 함수입니다. 따라서 프레임별로 엔티티 위치, 상태, 동작을 변경하고 싶다면 `OnUpdate` 함수에 스크립트를 작성합니다. 매개 변수로 **delta**를 사용하며, 이전 프레임에 걸린 시간 값(단위: 초)을 받습니다. **delta**를 활용하여 프레임 단위 구현을 할 수 있고, 특정 시간마다 액션을 제어할 수 있습니다. ```lua void OnUpdate(number delta) { if self._T.Time == nil then self._T.Time

[task] | instruction_following [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | OnInitialize와 OnBeginPlay의 호출 시점 차이 및 각 함수에서 보장되는 엔티티/컴포넌트 참조 범위를 비교하는 표로 정리하세요. [answer] | 제공된 문서에 따르면, `OnInitialize`와 `OnBeginPlay`는 로직 실행 시점과 참조 가능한 범위에서 명확한 차이를 보입니다. ### 1. 호출 시점 및 참조 범위 비교 | 구분 | OnInitialize | OnBeginPlay | | :--- | :--- | :--- | | **호출 시점** | 로직이 본격적으로 시작되는 시점 (로직 시작 후 1회 호출) | `OnInitialize` 호출 이후, `OnUpdate` 호출 직전에 1회 호출 | | **생성 완료 보장** | 해당 엔티티의 컴포넌트 생성 완료 시 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 본격적으로 로직이 시작되는 시점(`OnInitialize` 함수 호출 이후, `OnUpdate` 호출 직전)에 1회 호출되는 함수입니다. 엔티티의 `OnBeginPlay` 함수는 다른 엔티티와 컴포넌트가 모두 생성된 뒤에 호출됩니다. 동적으로 생성된 엔티티도 해당 엔티티의 컴포넌트가 모두 생성된 후에 `OnBeginPlay` 함수가 호출됩니다. 그러므로 `OnInitialize` 함수와는 달리 `OnBeginPlay` 함수는 다른 엔티티 및 컴포넌트의 참조가 보장됩니다. ```lua void OnBeginPlay() { lo

[task] | single_turn [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | 플레이어가 맵을 이동할 때마다 초기화가 필요한 상태 변수를 관리하려면 OnBeginPlay 대신 어떤 함수를 사용해야 하며 그 이유는 무엇인가요? [answer] | 플레이어가 맵을 이동할 때마다 초기화가 필요한 상태 변수를 관리하려면 `OnBeginPlay` 대신 **`OnMapEnter`** 함수를 사용해야 합니다. 그 이유는 두 함수의 호출 시점이 근본적으로 다르기 때문입니다. 1. **`OnBeginPlay`의 동작 방식**: * 서버 환경에서 플레이어 엔티티가 월드에 최초 진입하여 엔티티가 생성되는 시점에 **단 한 번만** 호출됩니다. * 이후 맵이 변경되어도 엔티티가 새로 생성되는 것이 아니므로 `OnBeginPlay`는 다시 호출되지 않습니다. 따라서 맵 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 예를 들어, 내 플레이어 엔티티가 **map01에서 map02로 이동**했다고 가정합니다. 이때 내 플레이어 엔티티의 스크립트 컴포넌트에 `OnMapEnter` 함수가 있었다면, map02로 이동할 때 내 플레이어 엔티티의 `OnMapEnter` 함수가 호출됩니다. 그런데 내 플레이어뿐만 아니라 다른 플레이어의 `OnMapEnter` 함수도 호출되는 것을 볼 수 있습니다. 클라이언트 상에서 보자면, 현재 내가 존재하는 맵에 다른 플레이어 엔티티가 생성된 것과 마찬가지이기 때문입니다. 하지만 서버상에서는 내 플레이어 엔티티가 map

[task] | code [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | OnInitialize에서 _EntityService:GetEntityByPath("/maps/map01/obj")를 호출하여 결과를 log로 출력하되, nil일 가능성에 대한 주석 설명을 포함하고, OnBeginPlay에서 self.Entity.Name을 log로 출력하는 스크립트를 작성해줘. [answer] | 요청하신 `OnInitialize`와 `OnBeginPlay` 함수를 포함한 mLua 스크립트 컴포넌트입니다. `OnInitialize`에서 다른 엔티티를 참조할 때 `nil`을 반환할 수 있으므로, 해당 부분에는 주석으로 주의 사항을 명시했습니다. ```lua Method: [server only] void OnInitialize() { -- OnInitialize는 엔티티와 컴포넌트가 생성된 직후에 호출되지만, -- 다른 엔티티나 컴포넌트가 아직 초기화되지 않았을 수 있습니다. local targetEn [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드에서 스크립트를 활용하면 크리에이터만의 독창적인 월드를 자유자재로 만들 수 있습니다. 스크립트를 작성할 때는 필요에 따라 기본 이벤트 함수를 활용하게 됩니다. **기본 이벤트 함수**란 다른 함수에서 직접 호출하지 않아도 **특정 조건이 되면 자동으로 호출되는 함수**를 말합니다. 이번 과정에서는 기본 이벤트 함수의 종류와 호출 시점을 알아봅시다. # 기본 이벤트 함수 추가하기 기본 이벤트 함수를 추가해 봅시다. 1. **Workspace - MyDesk**의 콘텍스트 메뉴에서 **Crea

[task] | code [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | 매 프레임 delta 값을 누적하여 1초가 지날 때마다 엔티티의 X 좌표를 10만큼 증가시키는 OnUpdate 스크립트를 작성해줘. [answer] | 요청하신 동작을 수행하기 위한 스크립트입니다. `OnUpdate` 함수의 매개변수 `delta`를 누적하여 1초가 지날 때마다 엔티티의 X 좌표를 10만큼 증가시킵니다. ```lua Property: [None] number TimeAccumulator = 0 Method: [server only] void OnUpdate(number delta) { self.TimeAccumulator = self.TimeAccumulator + delta if self.TimeAccumulator >= 1 then [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `OnBeginPlay` 함수 호출 이후, 프레임마다 호출되는 함수입니다. 따라서 프레임별로 엔티티 위치, 상태, 동작을 변경하고 싶다면 `OnUpdate` 함수에 스크립트를 작성합니다. 매개 변수로 **delta**를 사용하며, 이전 프레임에 걸린 시간 값(단위: 초)을 받습니다. **delta**를 활용하여 프레임 단위 구현을 할 수 있고, 특정 시간마다 액션을 제어할 수 있습니다. ```lua void OnUpdate(number delta) { if self._T.Time == nil then self._T.Time

[task] | two_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | 상점 UI에서 닫기 버튼을 눌렀을 때 UI가 제대로 숨겨지지 않거나, 다른 버튼 동작과 충돌하는 문제가 발생할 때 어떻게 디버깅하고 해결해야 하는가요? [answer] | 상점 UI의 닫기 버튼(`ShopCloseButton`)이 제대로 동작하지 않거나 다른 버튼과 충돌하는 문제는, 문서에 제시된 **Event Handler 연결**, **Entity 경로(Path) 설정**, **UI Group 가시성 제어** 순서로 점검하면 해결할 수 있습니다. ### 1. 문제 원인 분석 및 디버깅 방법 문서에서 상점 UI를 제어하는 핵심은 `UIManager` 컴포넌트 내의 `ShopGroup` 프로퍼티와 `OnClickButton` 메서드입니다. 다음 단계를 확인하세요. #### A. `ShopGrou [followup] | `ShopGroup` 엔티티 경로가 `/ui/UIGroup`으로 잘못 설정되었거나, `SetVisible(false, false)` 호출 시점에 `ShopGroup`이 nil 상태인 경우를 어떻게 확인하고 수정해야 하는지 구체적인 코드 예시를 보여주세요. [followup_answer] | `ShopGroup`이 `nil` 상태이거나 경로가 잘못 설정된 문제를 확인하고 해결하기 위해서는, `OnBeginPlay()`에서 엔티티를 가져오는 시점에 **로그 출력**을 통해 상태를 점검하고, 버튼 클릭 시 **nil 체크**를 수행하는 로직을 추가해야 합니다. 참고 문서에 제시된 구조를 바탕으로 구체적인 디버깅 및 수정 코드는 다음과 같습니다. ### 1. 문제 확인 및 수정 코드 `UIManager` 컴포넌트 스크립트에 아래 코드를 적용하여 `ShopGroup`이 올바르게 초기화되는지, 버튼 클릭 시 `nil` 상태 [scores] | [judge_reason] | [source_doc] | # 상점 UI 제작 1. 새로운 **UI Group**을 추가하고, **DefaultShow** 값을 **true**로 설정합니다. 2. 아래와 같이 UI엔티티를 추가하고 배치합니다. UI엔티티의 이름은 이미지와 동일해야 합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/1769512144899182516b8ee4d4248a16af41cc5d72f56.png "1") > **Tip.** > 이미지나 텍스트가 다른 UI엔티티에 가릴 경우 하이어라키 순서를 변경합니다.

[task] | code [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | 플레이어가 map02 맵에 입장할 때마다 엔티티의 Scale을 초기화하여 1.0으로 설정하고, map01에 입장할 때는 Scale을 2.0으로 설정하도록 OnMapEnter를 사용하는 스크립트를 작성해줘. [answer] | `OnMapEnter` 함수는 엔티티가 특정 맵에 입장할 때마다 호출되며, 매개 변수로 입장한 맵 엔티티를 전달받습니다. 이를 활용하여 `enteredMap.Name`을 확인하고, 맵 이름에 따라 `TransformComponent`의 `Scale` 값을 설정할 수 있습니다. ```lua void OnMapEnter(Entity enteredMap) { local myPlayer = self.Entity local transform = myPlayer.TransformComponent local scale = [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `OnBeginPlay` 함수 호출 이후, 프레임마다 호출되는 함수입니다. 따라서 프레임별로 엔티티 위치, 상태, 동작을 변경하고 싶다면 `OnUpdate` 함수에 스크립트를 작성합니다. 매개 변수로 **delta**를 사용하며, 이전 프레임에 걸린 시간 값(단위: 초)을 받습니다. **delta**를 활용하여 프레임 단위 구현을 할 수 있고, 특정 시간마다 액션을 제어할 수 있습니다. ```lua void OnUpdate(number delta) { if self._T.Time == nil then self._T.Time

[task] | instruction_following [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | _GetEntitiesByPath()_ 로 반환된 테이블을 순회하며 각 엔티티의 이름을 로그로 출력하는 코드만 출력하고 설명은 주석으로 작성하세요. [answer] | ```lua void OnBeginPlay() { -- 경로 "/maps/map01/EntityO/EntityB/EntityE"에 해당하는 모든 엔티티를 리스트 형태로 가져옵니다. local entityTable = _EntityService:GetEntitiesByPath("/maps/map01/EntityO/EntityB/EntityE") -- 반환된 값이 nil인 경우(해당 경로에 엔티티가 없는 경우) 처리 if entityTable == nil then return end [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 찾으려는 엔티티 경로(Path)를 매개 변수로 넘겨주면, 해당 경로의 엔티티를 반환하는 함수입니다. 가장 보편적으로 사용되는 함수입니다. * **매개 변수** | Parameter | Type | Description | | --- | --- | --- | | worldPath | string | 얻고자 하는 엔티티 경로를 넣어줍니다. 경로는 /maps/부터 시작해서 하위 엔티티들을 입력합니다. 예를 들어 다음과 같은 계층 구조에서 "object_1"의 경로는 다음과 같습니다. "/maps/map01

[task] | single_turn [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | OnBeginPlay와 OnMapEnter 함수의 호출 시점이 서버와 클라이언트에서 어떻게 다른지 설명해 주세요. [answer] | `OnBeginPlay`와 `OnMapEnter` 함수는 서버와 클라이언트 모두에서 작동하지만, 엔티티의 생명주기에서 호출되는 시점이 다릅니다. **1. OnBeginPlay** * **호출 시점**: 해당 엔티티가 월드에 **최초 진입하여 생성되는 단 한 번만** 호출됩니다. * **서버/클라이언트 공통 동작**: 서버와 클라이언트 모두에서 엔티티가 처음 생성될 때 1회씩 실행됩니다. * **주의점**: 플레이어가 맵을 이동하더라도 서버 상에서는 이미 존재했던 다른 플레이어 엔티티가 새로 생성되는 것이 아니므로, 기존 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 예를 들어, 내 플레이어 엔티티가 **map01에서 map02로 이동**했다고 가정합니다. 이때 내 플레이어 엔티티의 스크립트 컴포넌트에 `OnMapEnter` 함수가 있었다면, map02로 이동할 때 내 플레이어 엔티티의 `OnMapEnter` 함수가 호출됩니다. 그런데 내 플레이어뿐만 아니라 다른 플레이어의 `OnMapEnter` 함수도 호출되는 것을 볼 수 있습니다. 클라이언트 상에서 보자면, 현재 내가 존재하는 맵에 다른 플레이어 엔티티가 생성된 것과 마찬가지이기 때문입니다. 하지만 서버상에서는 내 플레이어 엔티티가 map

[task] | code [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | `OnSyncProperty` 이벤트를 활용하여 다른 플레이어의 `Speed` 프로퍼티가 변경되면 `log`로 변경 내용을 출력하는 스크립트를 작성해줘 [answer] | 제시된 참고 문서에는 `OnSyncProperty` 이벤트의 구체적인 시그니처(매개변수), 사용 방법, 또는 `Speed` 프로퍼티에 대한 설명이 포함되어 있지 않습니다. 문서에는 `OnMapEnter`, `OnMapLeave`, `OnBeginPlay` 함수의 동작 원리와 예제 코드만 제공되고 있습니다. 따라서, 제공된 문서 근거만으로는 `OnSyncProperty` 이벤트를 활용한 코드를 작성할 수 없습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 예를 들어, 내 플레이어 엔티티가 **map01에서 map02로 이동**했다고 가정합니다. 이때 내 플레이어 엔티티의 스크립트 컴포넌트에 `OnMapEnter` 함수가 있었다면, map02로 이동할 때 내 플레이어 엔티티의 `OnMapEnter` 함수가 호출됩니다. 그런데 내 플레이어뿐만 아니라 다른 플레이어의 `OnMapEnter` 함수도 호출되는 것을 볼 수 있습니다. 클라이언트 상에서 보자면, 현재 내가 존재하는 맵에 다른 플레이어 엔티티가 생성된 것과 마찬가지이기 때문입니다. 하지만 서버상에서는 내 플레이어 엔티티가 map

[task] | two_turn [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | self.Entity, Entity.Parent, Entity.Children을 통해 엔티티와 컴포넌트에 접근하는 구조와 방법은 무엇인가요? [answer] | 메이플스토리 월드에서 엔티티(Entity)와 컴포넌트(Component)는 상-하위 관계로 연결된 트리 구조를 이루며, 스크립트 컴포넌트 내에서 이 구조를 통해 다른 엔티티나 컴포넌트에 접근할 수 있습니다. 접근 방법은 다음과 같습니다. ### 1. 자기 자신의 엔티티 참조: `self.Entity` 스크립트가 붙어 있는 컴포넌트가 속한 엔티티 자체를 참조하려면 `self.Entity`를 사용합니다. 이를 통해 해당 엔티티의 이름(`Name`) 등 프로퍼티에 접근할 수 있습니다. ```lua void OnBeginPlay() { [followup] | Entity.Children으로 하위 엔티티 목록을 받아 특정 이름(예: "EntityD")의 엔티티를 찾을 때, 배열 순회 로직과 찾지 못했을 때의 예외 처리 방법은 어떻게 작성하나요? [followup_answer] | `Entity.Children`은 해당 엔티티의 모든 하위 엔티티를 테이블(목록) 형태로 반환합니다. 이 목록에서 특정 이름의 엔티티를 찾으려면 테이블을 순회하며 각 자식 엔티티의 `Name`을 비교해야 합니다. 찾지 못했을 경우를 대비해 변수를 초기값(빈 문자열 등)으로 설정하고, 순회 후 해당 값이 변경되지 않았는지 확인하여 예외를 처리하는 것이 일반적입니다. 다음은 `EntityD`라는 이름을 가진 하위 엔티티를 찾고, 찾지 못할 경우 로그를 출력한 뒤 함수를 종료하는 예시 코드입니다. ```lua void OnBeginP [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 엔티티와 컴포넌트 구조를 간략하게 이해하고, 스크립트를 통해 엔티티와 컴포넌트에 접근하는 방법을 알아봅니다. # 엔티티와 컴포넌트 구조 먼저 엔티티와 컴포넌트의 구조를 알아보겠습니다. 기본적으로 엔티티는 각기 다른 컴포넌트들로 구성되어 있고, 각각의 엔티티는 상위, 하위 관계로 연결되어 있습니다. 이 연결 구조를 이용하면 특정 컴포넌트에서 다른 엔티티나 컴포넌트로 접근할 수 있습니다. 아래 이미지는 엔티티 간의 상-하위 구조와 각 엔티티를 구성하는 컴포넌트를 도식화한 것입니다. 이후 이 구조를 바탕으로 설명

[task] | instruction_following [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | 서버 공간에서 _UserService.LocalPlayer에 접근할 때 반환되는 값과 그 이유를 2문장 이내로 설명하세요. [answer] | 서버 공간에서 `_UserService.LocalPlayer`에 접근하면 `nil`을 반환합니다. 이는 서버에 "내 플레이어"라는 개념이 없기 때문입니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 게임에 접속해 있는 모든 플레이어 엔티티를 딕셔너리 형태로 받아오는 읽기 전용 프로퍼티입니다. * Key: string UserId * Value: Entity PlayerEntity key 값인 UserId는 유저가 메이플스토리 월드에 가입 시 생성한 Id로 UserId와 플레이어 엔티티의 이름을 동일하게 사용하고 있습니다. ```lua void PrintUserEntitiesName() { log(_UserService:GetUserCount()) local playerEntitiesDic = _UserServi

[task] | instruction_following [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | 엔티티 경로를 정확히 입력하기 위한 팁과 _GetEntityByPath()_ 사용 예시를 포함해 3문장 이내로 작성하세요. [answer] | 엔티티 경로를 수동으로 입력하는 대신, 특정 엔티티의 콘텍스트 메뉴에서 **Copy Entity Path** 기능을 사용해 클립보드에 복사한 경로를 붙여넣으면 오타를 방지할 수 있습니다. `_EntityService:GetEntityByPath("/maps/map01/EntityO/EntityB/EntityE")` 와 같이 경로를 매개 변수로 전달하면 해당 엔티티를 반환하며, 존재하지 않는 경우 nil이 반환되므로 유효성 검사가 필요합니다. 다음 코드는 시작 시점에 엔티티를 가져와 이름이 존재하는지 확인하는 예시입니다. ```lu [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 찾으려는 엔티티 경로(Path)를 매개 변수로 넘겨주면, 해당 경로의 엔티티를 반환하는 함수입니다. 가장 보편적으로 사용되는 함수입니다. * **매개 변수** | Parameter | Type | Description | | --- | --- | --- | | worldPath | string | 얻고자 하는 엔티티 경로를 넣어줍니다. 경로는 /maps/부터 시작해서 하위 엔티티들을 입력합니다. 예를 들어 다음과 같은 계층 구조에서 "object_1"의 경로는 다음과 같습니다. "/maps/map01

[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | Stats 컴포넌트의 SkillGradeTable 과 DnaGradeTable 의 배열 길이(#operator)를 확인하여, 현재 등급이 테이블의 마지막 인덱스보다 크거나 같으면 "최종 등급 달성" 메시지를 SkillUpButtonText.Text 와 DnaUpButtonText.Text 에 설정하는 조건 분기 로직을 작성해줘. [answer] | `#` 연산자를 사용하여 `SkillGradeTable`과 `DnaGradeTable`의 배열 길이를 확인하고, 현재 등급(`CurrentSkillGrade`, `CurrentDnaGrade`)이 해당 길이보다 크거나 같을 경우 "최종 등급 달성" 메시지를 설정하는 로직은 다음과 같습니다. ```lua Method: [server only] void SetShopInfo() { local skillGrade = math.floor(self.Stats.CurrentSkillGrade) local dnaGrade = m [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua void SetShopInfo() { local skillGrade = math.floor(self.Stats.CurrentSkillGrade) local dnaGrade = math.floor(self.Stats.CurrentDnaGrade) self.SkillLevelText.Text = ("기술 레벨: "..skillGrade.."레벨") self.DnaLevelText.Text = ("DNA: "..self.Stats.DnaG

[task] | instruction_following [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | _UserService.UserEntities 프로퍼티의 Key와 Value 타입을 각각 string, Entity로 명시한 표로 정리하세요. [answer] | `_UserService.UserEntities` 프로퍼티의 Key와 Value 타입은 다음과 같습니다. | 구분 | 타입 | 설명 | | :--- | :--- | :--- | | Key | string | UserId | | Value | Entity | PlayerEntity | [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 게임에 접속해 있는 모든 플레이어 엔티티를 딕셔너리 형태로 받아오는 읽기 전용 프로퍼티입니다. * Key: string UserId * Value: Entity PlayerEntity key 값인 UserId는 유저가 메이플스토리 월드에 가입 시 생성한 Id로 UserId와 플레이어 엔티티의 이름을 동일하게 사용하고 있습니다. ```lua void PrintUserEntitiesName() { log(_UserService:GetUserCount()) local playerEntitiesDic = _UserServi

[task] | two_turn [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | `OnBeginPlay` 함수는 언제 호출되며, `OnInitialize`와 호출 시점 및 참조 보장 측면에서 어떤 차이가 있는가? [answer] | `OnBeginPlay`와 `OnInitialize` 함수의 호출 시점과 참조 보장 차이는 다음과 같습니다. ### 1. 호출 시점 * **`OnInitialize`**: 본격적인 로직이 시작되는 시점, 즉 `OnInitialize` 함수 호출 이후 `OnUpdate` 호출 직전에 **1회** 호출됩니다. * **`OnBeginPlay`**: 엔티티와 그 안에 포함된 모든 컴포넌트가 **모두 생성된 뒤에** 호출됩니다. 동적으로 생성된 엔티티의 경우에도 해당 엔티티의 컴포넌트가 모두 생성된 후에 호출됩니다. ### 2. [followup] | 동적으로 생성된 엔티티의 경우에도 `OnBeginPlay`가 컴포넌트 생성 완료 후에 호출되는지, 그리고 이 시점에 `_EntityService:GetEntityByPath`를 사용하여 다른 엔티티를 안전하게 접근하는 코드는 어떻게 작성되는지 설명해 주세요. [followup_answer] | ### 동적 생성 엔티티의 `OnBeginPlay` 호출 시점 참고 문서에 따르면, 동적으로 생성된 엔티티의 경우에도 해당 엔티티의 **컴포넌트가 모두 생성된 후에** `OnBeginPlay` 함수가 호출됩니다. 이는 정적으로 배치된 엔티티와 동일한 생명주기 규칙이 적용됨을 의미합니다. 따라서 `OnBeginPlay` 함수 내부에서는 다음과 같은 참조가 보장됩니다: 1. `self.Entity`를 통한 자기 자신 엔티티 참조 2. `myEntity.컴포넌트 이름`을 통한 같은 엔티티 내 다른 컴포넌트 참조 3. `_Enti [scores] | [judge_reason] | [source_doc] | 본격적으로 로직이 시작되는 시점(`OnInitialize` 함수 호출 이후, `OnUpdate` 호출 직전)에 1회 호출되는 함수입니다. 엔티티의 `OnBeginPlay` 함수는 다른 엔티티와 컴포넌트가 모두 생성된 뒤에 호출됩니다. 동적으로 생성된 엔티티도 해당 엔티티의 컴포넌트가 모두 생성된 후에 `OnBeginPlay` 함수가 호출됩니다. 그러므로 `OnInitialize` 함수와는 달리 `OnBeginPlay` 함수는 다른 엔티티 및 컴포넌트의 참조가 보장됩니다. ```lua void OnBeginPlay() { lo

[task] | single_turn [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | OnMapLeave에서 self.Entity.TransformComponent.Scale을 수정할 때, 매개변수인 leftMap.Name을 직접 참조하는 것과 어떤 차이가 있나요? [answer] | `OnMapLeave` 함수에서 `self.Entity.TransformComponent.Scale`을 수정하는 것(플레이어 엔티티의 스케일 변경)과 매개변수인 `leftMap.Name`을 직접 참조하는 것(퇴장한 맵의 이름 확인)은 서로 다른 대상에 대한 접근이므로 기능적으로 완전히 다릅니다. 1. **`self.Entity.TransformComponent.Scale` 수정**: * **대상**: 스크립트가 부착된 엔티티 자체(예: 플레이어). * **목적**: 엔티티의 시각적 크기나 물리적 규모를 변경 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 예를 들어, 내 플레이어 엔티티가 **map01에서 map02로 이동**했다고 가정합니다. 이때 내 플레이어 엔티티의 스크립트 컴포넌트에 `OnMapEnter` 함수가 있었다면, map02로 이동할 때 내 플레이어 엔티티의 `OnMapEnter` 함수가 호출됩니다. 그런데 내 플레이어뿐만 아니라 다른 플레이어의 `OnMapEnter` 함수도 호출되는 것을 볼 수 있습니다. 클라이언트 상에서 보자면, 현재 내가 존재하는 맵에 다른 플레이어 엔티티가 생성된 것과 마찬가지이기 때문입니다. 하지만 서버상에서는 내 플레이어 엔티티가 map

[task] | two_turn [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | OnBeginPlay와 OnMapEnter 함수의 호출 시점 및 서버/클라이언트에서의 동작 차이점에 대해 설명해 주세요. [answer] | `OnBeginPlay`와 `OnMapEnter` 함수는 엔티티의 생명주기에서 서로 다른 시점에 호출되며, 서버와 클라이언트 환경에서의 동작 방식에도 명확한 차이가 있습니다. ### 1. OnBeginPlay 함수 * **호출 시점:** 엔티티가 **월드에 진입하여 생성되는 단 한 번만** 호출됩니다. * **서버/클라이언트 차이:** * **서버:** 서버 상에서는 해당 월드에 최초 진입하는 순간에만 엔티티가 생성되므로, `OnBeginPlay`는 엔티티 생성 시점에 딱 한 번 실행됩니다. 이후 맵을 이동하더라 [followup] | 내 플레이어 엔티티가 map01에서 map02로 이동할 때, 클라이언트와 서버 각각에서 OnBeginPlay와 OnMapEnter가 어떻게 호출되는지 구체적인 시나리오를 통해 차이점을 정리해 주세요. [followup_answer] | 내 플레이어 엔티티가 map01에서 map02로 이동하는 시나리오를 기준으로, 클라이언트와 서버에서 `OnBeginPlay`와 `OnMapEnter`가 어떻게 호출되는지 정리하면 다음과 같습니다. ### 1. 서버(Server)에서의 동작 서버에서는 엔티티의 생명주기가 물리적 생성/소멸에 기반하기 때문에 동작이 명확합니다. * **OnBeginPlay**: * 내 플레이어가 해당 **월드(World)에 최초 진입**하여 엔티티가 생성되는 순간에만 **1회** 호출됩니다. * map01에서 map02로 맵 [scores] | [judge_reason] | [source_doc] | 예를 들어, 내 플레이어 엔티티가 **map01에서 map02로 이동**했다고 가정합니다. 이때 내 플레이어 엔티티의 스크립트 컴포넌트에 `OnMapEnter` 함수가 있었다면, map02로 이동할 때 내 플레이어 엔티티의 `OnMapEnter` 함수가 호출됩니다. 그런데 내 플레이어뿐만 아니라 다른 플레이어의 `OnMapEnter` 함수도 호출되는 것을 볼 수 있습니다. 클라이언트 상에서 보자면, 현재 내가 존재하는 맵에 다른 플레이어 엔티티가 생성된 것과 마찬가지이기 때문입니다. 하지만 서버상에서는 내 플레이어 엔티티가 map

[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | Stats 컴포넌트의 CurrentMoney 값과 다음 등급의 Cost 값을 비교하여, 금액이 충분하지 않을 경우 SkillFontColor 와 DnaFontColor 를 Color(1,0,0,1) 로, 충분할 경우 Color(1,1,1,1) 로 설정하고 이 색상들을 각각의 버튼 텍스트 컴포넌트의 FontColor 속성에 할당하는 SetShopInfo() 내부 로직을 작성해줘. [answer] | 제공된 문서에 포함된 `SetShopInfo()` 메서드 구현 로직을 바탕으로 요청하신 코드를 작성했습니다. ```lua Method: [server only] void SetShopInfo() { local skillGrade = math.floor(self.Stats.CurrentSkillGrade) local dnaGrade = math.floor(self.Stats.CurrentDnaGrade) self.SkillLevelText.Text = ("기술 레벨: "..skillGrade.."레벨" [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua void SetShopInfo() { local skillGrade = math.floor(self.Stats.CurrentSkillGrade) local dnaGrade = math.floor(self.Stats.CurrentDnaGrade) self.SkillLevelText.Text = ("기술 레벨: "..skillGrade.."레벨") self.DnaLevelText.Text = ("DNA: "..self.Stats.DnaG

[task] | code [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | self.Entity 를 통해 현재 엔티티를 참조한 후, Entity:GetChildByName() 메서드를 사용하여 이름이 "Target" 인 하위 엔티티를 직접 가져와 그 이름을 log 로 출력하는 스크립트를 작성해줘 [answer] | ```lua Method: [server only] void OnBeginPlay() { local myEntity = self.Entity local targetEntity = myEntity:GetChildByName("Target") log(targetEntity.Name) } ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 엔티티와 컴포넌트 구조를 간략하게 이해하고, 스크립트를 통해 엔티티와 컴포넌트에 접근하는 방법을 알아봅니다. # 엔티티와 컴포넌트 구조 먼저 엔티티와 컴포넌트의 구조를 알아보겠습니다. 기본적으로 엔티티는 각기 다른 컴포넌트들로 구성되어 있고, 각각의 엔티티는 상위, 하위 관계로 연결되어 있습니다. 이 연결 구조를 이용하면 특정 컴포넌트에서 다른 엔티티나 컴포넌트로 접근할 수 있습니다. 아래 이미지는 엔티티 간의 상-하위 구조와 각 엔티티를 구성하는 컴포넌트를 도식화한 것입니다. 이후 이 구조를 바탕으로 설명

[task] | instruction_following [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | _GetEntityByPath()_ 와 _GetEntitiesByPath()_ 의 반환값 차이를 표로 정리해서 설명하세요. [answer] | `_EntityService:GetEntityByPath()`와 `_EntityService:GetEntitiesByPath()`의 반환값 차이는 다음과 같습니다. | 함수명 | 반환 값 | 설명 | | :--- | :--- | :--- | | `GetEntityByPath()` | `Entity` 또는 `nil` | 매개 변수로 입력한 경로와 일치하는 엔티티가 있으면 **하나**의 엔티티를 반환합니다.<br>경로 값과 일치하는 엔티티가 여러 개일 경우, **가장 먼저 찾은 엔티티만** 반환합니다.<br>일치하는 엔티티가 없으면 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 찾으려는 엔티티 경로(Path)를 매개 변수로 넘겨주면, 해당 경로의 엔티티를 반환하는 함수입니다. 가장 보편적으로 사용되는 함수입니다. * **매개 변수** | Parameter | Type | Description | | --- | --- | --- | | worldPath | string | 얻고자 하는 엔티티 경로를 넣어줍니다. 경로는 /maps/부터 시작해서 하위 엔티티들을 입력합니다. 예를 들어 다음과 같은 계층 구조에서 "object_1"의 경로는 다음과 같습니다. "/maps/map01

[task] | code [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | OnUpdate(number delta) 생명주기 메서드 내에서 self.Entity.Parent 를 호출하여 상위 엔티티의 이름을 매 프레임마다 log 로 출력하는 스크립트를 작성해줘 [answer] | 요청하신 조건에 따라 `OnUpdate` 메서드 내에서 매 프레임마다 상위 엔티티의 이름을 출력하는 스크립트는 다음과 같습니다. ```lua Method: [server only] void OnUpdate(number delta) { local parentEntity = self.Entity.Parent log(parentEntity.Name) } ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 엔티티와 컴포넌트 구조를 간략하게 이해하고, 스크립트를 통해 엔티티와 컴포넌트에 접근하는 방법을 알아봅니다. # 엔티티와 컴포넌트 구조 먼저 엔티티와 컴포넌트의 구조를 알아보겠습니다. 기본적으로 엔티티는 각기 다른 컴포넌트들로 구성되어 있고, 각각의 엔티티는 상위, 하위 관계로 연결되어 있습니다. 이 연결 구조를 이용하면 특정 컴포넌트에서 다른 엔티티나 컴포넌트로 접근할 수 있습니다. 아래 이미지는 엔티티 간의 상-하위 구조와 각 엔티티를 구성하는 컴포넌트를 도식화한 것입니다. 이후 이 구조를 바탕으로 설명

[task] | two_turn [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | _EntityService:GetEntityByPath() 함수의 반환 값이 nil일 때를 어떻게 처리해야 하나요? [answer] | `_EntityService:GetEntityByPath()` 함수는 매개 변수로 입력한 경로와 일치하는 엔티티가 없으면 `nil`을 반환합니다. 따라서 이 함수를 호출한 후 반드시 반환 값이 `nil`인지 확인하는 처리를 해야 합니다. 반환 값이 `nil`인 경우 해당 엔티티에 접근하려는 코드를 실행하지 않고 함수를 종료하거나, 오류 메시지를 출력하는 것이 일반적입니다. 아래는 `_EntityService:GetEntityByPath()`의 반환 값이 `nil`일 때를 처리하는 예시 코드입니다. ```lua void OnBe [followup] | isvalid() 함수를 사용하여 nil 여부를 확인한 후, 해당 엔티티가 없으면 OnBeginPlay()에서 즉시 return 하도록 하는 예제 코드를 작성해 주세요. [followup_answer] | ```lua void OnBeginPlay() { local EntityE = _EntityService:GetEntityByPath("/maps/map01/EntityO/EntityB/EntityE") if isvalid(EntityE) == false then return end log(EntityE.Name) } ``` [scores] | [judge_reason] | [source_doc] | 찾으려는 엔티티 경로(Path)를 매개 변수로 넘겨주면, 해당 경로의 엔티티를 반환하는 함수입니다. 가장 보편적으로 사용되는 함수입니다. * **매개 변수** | Parameter | Type | Description | | --- | --- | --- | | worldPath | string | 얻고자 하는 엔티티 경로를 넣어줍니다. 경로는 /maps/부터 시작해서 하위 엔티티들을 입력합니다. 예를 들어 다음과 같은 계층 구조에서 "object_1"의 경로는 다음과 같습니다. "/maps/map01

[task] | single_turn [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | self.Entity를 통해 자기 자신 엔티티를 가져온 뒤, 그 부모 엔티티의 이름까지 출력하고 싶은데 어떤 순서로 코드를 작성해야 하나요? [answer] | `self.Entity`로 현재 스크립트가 붙어 있는 엔티티를 먼저 받아오고, 그 엔티티의 `Parent` 속성을 통해 상위 엔티티를 참조한 뒤 `Name`을 출력하면 됩니다. 구체적인 작성 순서는 다음과 같습니다. 1. `self.Entity`를 통해 현재 엔티티를 로컬 변수에 저장합니다. 2. 저장한 엔티티의 `.Parent`를 통해 상위 엔티티를 가져옵니다. 3. 상위 엔티티의 `.Name`을 `log`로 출력합니다. 아래는 이를 구현한 코드 예시입니다. ```lua void OnBeginPlay() { - [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 엔티티와 컴포넌트 구조를 간략하게 이해하고, 스크립트를 통해 엔티티와 컴포넌트에 접근하는 방법을 알아봅니다. # 엔티티와 컴포넌트 구조 먼저 엔티티와 컴포넌트의 구조를 알아보겠습니다. 기본적으로 엔티티는 각기 다른 컴포넌트들로 구성되어 있고, 각각의 엔티티는 상위, 하위 관계로 연결되어 있습니다. 이 연결 구조를 이용하면 특정 컴포넌트에서 다른 엔티티나 컴포넌트로 접근할 수 있습니다. 아래 이미지는 엔티티 간의 상-하위 구조와 각 엔티티를 구성하는 컴포넌트를 도식화한 것입니다. 이후 이 구조를 바탕으로 설명

[task] | code [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | `OnMapEnter`와 `OnMapLeave`를 조합하여 특정 맵("map01")에서 퇴장할 때마다 플레이어의 `TransformComponent.Position`을 맵 중앙 좌표로 재설정하는 스크립트를 작성해줘 [answer] | `OnMapLeave` 이벤트 핸들러를 사용하여 `map01`에서 퇴장할 때 플레이어의 위치를 재설정하는 스크립트입니다. 참고: 질문에서 "맵 중앙 좌표"라고 하셨으나, 제공된 참고 문서에는 맵의 중앙 좌표를 가져오는 API나 프로퍼티가 정의되어 있지 않습니다. 따라서 아래 코드는 **중앙 좌표를 구할 수 있는 메서드나 프로퍼티가 존재한다고 가정**하고, 해당 좌표(`local centerPos`)를 `Position`에 대입하는 구조로 작성했습니다. 실제 제작 시에는 맵 중앙 좌표를 구하는 올바른 API 또는 상수 값을 `cen [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 예를 들어, 내 플레이어 엔티티가 **map01에서 map02로 이동**했다고 가정합니다. 이때 내 플레이어 엔티티의 스크립트 컴포넌트에 `OnMapEnter` 함수가 있었다면, map02로 이동할 때 내 플레이어 엔티티의 `OnMapEnter` 함수가 호출됩니다. 그런데 내 플레이어뿐만 아니라 다른 플레이어의 `OnMapEnter` 함수도 호출되는 것을 볼 수 있습니다. 클라이언트 상에서 보자면, 현재 내가 존재하는 맵에 다른 플레이어 엔티티가 생성된 것과 마찬가지이기 때문입니다. 하지만 서버상에서는 내 플레이어 엔티티가 map

[task] | code [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | `_EntityService`와 `OnBeginPlay` 함수를 사용하여 경로 "/maps/map01/player" 를 가진 엔티티를 조회하고, 해당 엔티티의 이름과 "Hello MapleStory Worlds" 를 연결한 문자열을 콘솔에 출력하는 스크립트를 작성해줘 [answer] | `OnBeginPlay` 함수는 다른 엔티티와 컴포넌트가 모두 생성된 후에 호출되므로, `_EntityService:GetEntityByPath`를 사용하여 다른 엔티티를 참조하기에 적절한 시점입니다. 요청하신 경로 `/maps/map01/player`의 엔티티를 조회하고 이름과 문자열을 연결하여 출력하는 스크립트는 다음과 같습니다. ```lua Method: [server only] void OnBeginPlay() { local targetEntity = _EntityService:GetEntityByPath("/ma [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 본격적으로 로직이 시작되는 시점(`OnInitialize` 함수 호출 이후, `OnUpdate` 호출 직전)에 1회 호출되는 함수입니다. 엔티티의 `OnBeginPlay` 함수는 다른 엔티티와 컴포넌트가 모두 생성된 뒤에 호출됩니다. 동적으로 생성된 엔티티도 해당 엔티티의 컴포넌트가 모두 생성된 후에 `OnBeginPlay` 함수가 호출됩니다. 그러므로 `OnInitialize` 함수와는 달리 `OnBeginPlay` 함수는 다른 엔티티 및 컴포넌트의 참조가 보장됩니다. ```lua void OnBeginPlay() { lo

[task] | single_turn [pass] | ⏳ 미판정 [title] | MSW 기본 이벤트 함수 [question] | OnBeginPlay 함수와 OnMapEnter 함수가 호출되는 조건이 어떻게 다르며, 맵 이동 시 초기화가 필요한 경우 각각의 함수를 어떻게 구분해서 적용해야 하나요? [answer] | `OnBeginPlay`와 `OnMapEnter` 함수는 엔티티의 생명주기에서 서로 다른 시점에 호출되며, 이는 맵 이동 시 초기화 로직을 구성하는 방식에 직접적인 영향을 줍니다. ### 1. 호출 조건 차이 * **`OnBeginPlay`**: * 엔티티가 **생성될 때마다** 1회 호출됩니다. * 엔티티가 처음 월드에 로드되거나 스폰되는 시점에 실행됩니다. * 이 함수 호출 이후에는 다른 엔티티나 컴포넌트의 참조가 보장되므로, 초기화 로직을 작성하기에 적합한 시점입니다. * **`On [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `OnBeginPlay` 함수 호출 이후, 프레임마다 호출되는 함수입니다. 따라서 프레임별로 엔티티 위치, 상태, 동작을 변경하고 싶다면 `OnUpdate` 함수에 스크립트를 작성합니다. 매개 변수로 **delta**를 사용하며, 이전 프레임에 걸린 시간 값(단위: 초)을 받습니다. **delta**를 활용하여 프레임 단위 구현을 할 수 있고, 특정 시간마다 액션을 제어할 수 있습니다. ```lua void OnUpdate(number delta) { if self._T.Time == nil then self._T.Time

[task] | instruction_following [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | _UserService:GetUserEntityByUserID() 함수의 매개 변수와 반환 값 처리 로직을 코드만 출력하고 설명은 주석으로 작성하세요. [answer] | ```lua Method: [server only] void GetUserEntityByUserIDExample() { -- 매개 변수: string 타입의 UserId (예: "123456789") local targetUserId = "123456789" -- _UserService:GetUserEntityByUserID() 함수 호출 -- 반환 값: Entity 타입의 플레이어 엔티티 또는 nil local playerEntity = _UserService:GetUserEntityByUse [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 게임에 접속해 있는 모든 플레이어 엔티티를 딕셔너리 형태로 받아오는 읽기 전용 프로퍼티입니다. * Key: string UserId * Value: Entity PlayerEntity key 값인 UserId는 유저가 메이플스토리 월드에 가입 시 생성한 Id로 UserId와 플레이어 엔티티의 이름을 동일하게 사용하고 있습니다. ```lua void PrintUserEntitiesName() { log(_UserService:GetUserCount()) local playerEntitiesDic = _UserServi

[task] | instruction_following [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | _Entity.CurrentMap_ 프로퍼티를 사용하여 현재 엔티티가 속한 맵을 조회하는 과정을 단계별 번호 목록으로 3단계 이내로 요약하여 작성하세요. [answer] | 1. `self.Entity`를 통해 현재 스크립트가 속한 엔티티를 참조합니다. 2. 해당 엔티티의 `CurrentMap` 프로퍼티에 접근하여 현재 속해 있는 맵 엔티티를 가져옵니다. 3. 가져온 맵 엔티티가 유효한지 `isvalid` 함수로 확인 후, 필요한 정보(예: `Name`)를 조회합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 매개 변수로 엔티티 ID를 넘겨주면 해당 ID의 엔티티를 반환하는 함수입니다. 엔티티의 계층 구조가 동적으로 변경되거나 엔티티의 이름이 바뀌면서 경로가 변경될 여지가 있으면, 유니크한 ID를 이용해 엔티티를 받아올 수 있는 GetEntity를 사용하는 것이 효율적입니다. * **매개 변수** | Parameter | Type | Description | | --- | --- | --- | | ID | string | 얻고자 하는 엔티티 ID를 넣어줍니다. 엔티티의 콘텍스트 메뉴에서 **Copy Entity I

[task] | code [pass] | ⏳ 미판정 [title] | 엔티티와 컴포넌트 참조 [question] | self.Entity 와 Entity.Parent 를 활용하여 OnBeginPlay() 에서 자기 자신과 상위 엔티티의 이름을 log 로 출력하는 스크립트를 작성해줘 [answer] | `self.Entity`와 `Entity.Parent`를 활용하여 자기 자신과 상위 엔티티의 이름을 `OnBeginPlay()`에서 출력하는 스크립트는 다음과 같습니다. ```lua Method: [server only] void OnBeginPlay() { local myEntity = self.Entity log(myEntity.Name) local parentEntity = myEntity.Parent log(parentEntity.Name) } ``` **설명:** 1. `self.Entit [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 엔티티와 컴포넌트 구조를 간략하게 이해하고, 스크립트를 통해 엔티티와 컴포넌트에 접근하는 방법을 알아봅니다. # 엔티티와 컴포넌트 구조 먼저 엔티티와 컴포넌트의 구조를 알아보겠습니다. 기본적으로 엔티티는 각기 다른 컴포넌트들로 구성되어 있고, 각각의 엔티티는 상위, 하위 관계로 연결되어 있습니다. 이 연결 구조를 이용하면 특정 컴포넌트에서 다른 엔티티나 컴포넌트로 접근할 수 있습니다. 아래 이미지는 엔티티 간의 상-하위 구조와 각 엔티티를 구성하는 컴포넌트를 도식화한 것입니다. 이후 이 구조를 바탕으로 설명

← → 방향키로 페이지 이동 · 숫자 입력 후 Enter로 점프