본문 바로가기

환경 변수와 플레이어 행동 반응

날씨·시간·자원 같은 환경 변수를 플레이어 행동과 양방향으로 연결해 상황에 따라 달라지는 게임 규칙을 만듭니다.

개별 오브젝트 반응을 만들었다면, 이제는 레벨 전체를 움직이는 변수까지 연결해야 합니다.

이번 절에서는 환경 변수(Environmental Variables)와 플레이어 행동을 연결합니다.

날씨, 시간, 자원 상태처럼 시스템 단위의 값이 플레이어 행동에 반응하고, 반대로 플레이어 전략도 그 변수에 의해 바뀌는 구조를 만드는 것이 목표입니다.

이 연결이 잘 설계되면 레벨은 이벤트 집합이 아니라 유기적인 생태계처럼 동작합니다.

플레이어는 매 순간 동일한 맵에서도 다른 결과를 경험하게 됩니다.


환경 변수와 플레이어 행동 연동의 중요성

환경 변수와 플레이어 행동의 상호작용은 게임 세계의 몰입도와 게임 플레이의 전략적 깊이를 극대화합니다.

  • 동적인 세계 조성: 플레이어의 행동이 환경 변수에 영향을 주거나, 환경 변화가 새로운 도전 조건으로 이어지도록 상태를 연결합니다.
  • 전략적 깊이 추가: 날씨, 낮/밤 주기, 자원 고갈 등 환경 변수를 활용하여 플레이어가 전략적으로 행동하거나, 상황에 맞는 판단을 내리도록 유도합니다.
  • 내러티브 및 분위기 강화: 환경 변화를 통해 스토리를 진행하거나, 레벨의 분위기(예: 폭풍우 치는 밤)를 극대화할 수 있습니다.
  • 재플레이 가치 증대: 동일한 레벨이라도 환경 변수의 변화나 플레이어의 선택에 따라 매번 다른 경험을 제공함으로써 재플레이 가치를 높입니다.

주요 환경 변수와 플레이어 행동 연동 개념

환경 변수와 플레이어 반응은 입력, 조건, 결과가 분리되어 있어야 수정과 디버깅이 쉽습니다.

언리얼 엔진에서 환경 변수와 플레이어 행동을 연동하는 데 사용되는 주요 개념과 기술들을 살펴보겠습니다.

날씨 및 시간 시스템 연동

이전 6장에서 다룬 날씨 및 시간 시스템은 가장 대표적인 환경 변수입니다.

이제 이를 플레이어 행동과 연동하는 방법을 생각해 봅시다.

  • 플레이어 행동 -> 날씨/시간 변화
    • 마법/능력: 플레이어의 특정 마법 능력(예: 비를 부르는 주문, 시간 가속)이 날씨 시스템이나 시간 시스템에 직접적인 영향을 미치도록 구현합니다.
      • 구현: 플레이어 캐릭터 블루프린트에서 입력 이벤트가 발생하면, 6장에서 만든 BP_WeatherSystem 또는 BP_TimeOfDaySystem 참조를 가져옵니다. 이후 직접 구현한 함수/커스텀 이벤트로 상태를 바꾸고 관련 표현을 갱신합니다. SetCurrentWeather는 예시 함수명이며 변수에 값을 대입하는 것만으로 후속 연출이 자동 실행되지는 않습니다.
    • 특정 오브젝트 조작: 레벨의 제어판을 조작하여 인공 강우 시스템을 가동하거나, 발전소를 가동하여 낮/밤 주기를 변경하는 등의 상호작용.
  • 날씨/시간 변화 -> 플레이어 행동 반응
    • 이동 속도: 비나 눈이 올 때 플레이어 캐릭터의 이동 속도(Character Movement Component의 Max Walk Speed나 Ground Friction)를 동적으로 조절합니다.
    • 시야 제한: 밤이나 안개 낀 날에는 Post Process Volume의 노출(Exposure)이나 Exponential Height Fog의 밀도(Fog Density)를 조절하여 플레이어의 시야를 제한합니다.
    • NPC 행동 변화: 날씨나 시간에 따라 NPC의 순찰 경로, 행동 패턴, 스폰/디스폰 여부를 변경하여 플레이어의 전략에 영향을 미칩니다. (예: 밤에는 더 위험한 적 등장, 비가 오면 NPC가 실내로 대피)

자원 시스템 (Resource System) 연동

나무, 광물, 식량 등 플레이어가 채집하거나 소비하는 자원은 중요한 환경 변수가 될 수 있습니다.

  • 플레이어 행동 -> 자원 변화
    • 채집/소비: 플레이어가 나무를 베거나 광물을 채집하면 해당 자원 오브젝트의 수량이 줄어들거나, 파괴되어 사라지도록 합니다.
      • 구현: 자원 오브젝트 블루프린트(예: BP_Tree, BP_Ore)에 ResourceAmount 변수를 두고, 플레이어의 상호작용(Interact 이벤트) 시 이 값을 감소시킵니다. ResourceAmount가 0이 되면 오브젝트를 Destroy Actor하거나 숨깁니다.
    • 건설/생산: 플레이어가 자원을 소모하여 구조물을 건설하거나 아이템을 생산하면, 인벤토리의 자원 수가 감소하도록 합니다.
  • 자원 변화 -> 환경 반응
    • 자원 고갈: 특정 지역의 자원이 고갈되면 해당 지역의 경관이 황폐하게 변하거나, 새로운 자원이 재생성되기까지의 시간이 길어지는 등의 환경적 피드백을 제공합니다.
    • 생태계 변화: 특정 자원의 고갈이 다른 동물 NPC의 스폰이나 행동에 영향을 미치는 복합적인 시스템을 구축할 수 있습니다.

환경 상태 변화

레벨 자체의 특정 상태를 변수로 두고, 플레이어의 행동에 따라 이 상태를 전환합니다.

  • 활성화/비활성화 상태: 플레이어가 스위치를 누르면 다리가 활성화되어 이동 가능하게 되거나, 레이저 함정이 비활성화되는 등.
    • 구현: BP_Bridge와 같은 액터에 bIsActive 불리언 변수를 두고, 스위치 블루프린트에서 이 변수를 토글합니다. 직접 작성한 상태 적용 함수가 bIsActive 변경과 Timeline·콜리전 변경을 함께 수행하도록 합니다.
  • 오염/정화 상태: 플레이어의 행동(예: 오염된 물에 독성 물질 투하)으로 인해 특정 지역이 오염되거나, 반대로 정화되는 과정을 시뮬레이션할 수 있습니다.
    • 구현: Post Process Volume의 컬러 그레이딩(Color Grading)을 변경하여 오염된 지역의 색감을 어둡고 탁하게 만들거나, 파티클 시스템으로 오염된 공기 효과를 추가합니다. 플레이어가 정화제를 사용하면 해당 파라미터들을 원래대로 돌립니다.
  • 온도/습도 변화: 특정 오브젝트(용광로, 에어컨)의 작동으로 주변 환경의 온도나 습도가 변화하고, 이 변화가 다른 환경 요소(물체가 얼거나 녹는 현상, 식물의 성장)에 영향을 미치도록 합니다.

동적 이벤트 (Dynamic Events) 트리거

환경 변수나 플레이어의 특정 행동이 게임 세계에서 예상치 못한 동적 이벤트를 발생시키도록 합니다.

  • 플레이어 위치 기반: 플레이어가 특정 지역에 진입하면 지진이 발생하거나, 몬스터 무리가 습격해 오는 등.
  • 시간 기반: 특정 시간(예: 자정)이 되면 특정 문이 열리거나, 유령이 나타나는 등.
  • 조건 기반: 특정 몬스터를 모두 처치하거나, 모든 퍼즐 조각을 모으면 숨겨진 보스 몬스터가 등장하거나, 새로운 지역이 개방되는 등.
    • 구현: Game Mode나 Game State 블루프린트에 CurrentQuestState 또는 NumEnemiesKilled와 같은 변수를 두고, 이 변수 값이 특정 조건을 만족하면 새로운 이벤트(예: Spawn Actor From Class, Play Level Sequence, Set Visibility)를 트리거합니다.

환경 변수와 플레이어 행동 연동 구현 예시

이 실습의 자원 수량은 광맥 액터가 소유하고, 입력은 플레이어가 받아 광맥의 채집 함수에 전달합니다.

조종 가능한 Character와 Interact 입력, 8장 2절의 현재 대상 Trace를 먼저 준비합니다. PlayerInventory는 엔진이 자동 제공하는 변수 이름이 아닙니다. 첫 확인에는 플레이어의 Integer 변수 OreCount를 0으로 두고, MineResource가 성공한 경우에만 OreCount에 1을 더해 Print String으로 확인해도 됩니다. 이 단순 수량 확인을 끝낸 뒤 슬롯·용량·아이템 종류를 가진 인벤토리로 확장합니다.

시각 변화를 확인할 M_Ore에는 Texture Sample Parameter 2D를 만들고 이름을 OreStateTexture로 정해 RGB를 Base Color에 연결합니다. InitialTexture와 MinedTexture에는 직접 선택한 두 Texture2D 에셋을 지정합니다. BeginPlay에서 M_Ore를 Parent로 Dynamic Material Instance를 만들고 반환값을 OreMID에 저장한 다음 OreMesh의 재질 슬롯 0에 할당합니다. 초기값과 고갈값을 바꿀 때는 OreMID를 Target으로, 같은 OreStateTexture 이름으로 Texture Parameter를 설정합니다. 같은 이름의 파라미터가 없거나 생성한 인스턴스를 메시 슬롯에 할당하지 않았다면 수량은 줄어도 보이는 표면은 바뀌지 않습니다.

간단한 자원 채집 시스템을 통해 환경 변수와 플레이어 행동의 연동을 구현해 봅시다.

BP_OreVein (광물 자원) 블루프린트 생성
  • Static Mesh (OreMesh) 컴포넌트: 광물 모델 할당 (예: Cube 또는 SM_Ore)
  • Box Collision (InteractionTrigger): 오버랩 전용 트리거 볼륨 설정 (Custom에서 Pawn=Overlap, 나머지=Ignore, 양쪽 Generate Overlap Events 활성화)
  • 변수: ResourceAmount (Integer, 기본값: 3), MinedTexture (Texture2D, 광물 채집 후 변화할 텍스처), InitialTexture (Texture2D, 초기 광물 텍스처)
  • BeginPlay에서 OreMesh에 Create Dynamic Material Instance를 적용해 참조를 저장하고, 머티리얼에 만든 텍스처 파라미터를 InitialTexture로 초기화합니다.
  • 이벤트 그래프
    • OnComponentBeginOverlap / OnComponentEndOverlap (InteractionTrigger): 플레이어 캐스트 후 UI 프롬프트 표시/숨김.
    • MineResource 함수 (요청 플레이어를 입력, Success Boolean 반환)
      • 요청 플레이어 참조가 유효하고 InteractionTrigger에 오버랩 중인지 확인합니다. 실패하면 Success=False로 반환합니다.
      • ResourceAmount가 0보다 큰지 확인하고, 아니면 Success=False로 반환합니다.
      • ResourceAmount를 1 감소시킵니다.
      • Print String으로 광물 채집! 남은 광물: [ResourceAmount] 메시지 출력.
      • Spawn Emitter At Location (채집 파티클), Play Sound At Location (채집 사운드) 추가.
      • ResourceAmount가 0이 되었는지 확인합니다.
        • True일 경우
          • 저장한 Dynamic Material Instance의 텍스처 파라미터를 MinedTexture로 바꿉니다. Texture2D를 Material Interface 입력인 Set Material에 직접 연결할 수는 없습니다.
          • Set Collision Enabled (InteractionTrigger)를 No Collision으로 설정하여 더 이상 상호작용 불가능하게 만듭니다.
          • 플레이어의 현재 후보가 이 광맥이면 후보·프롬프트를 즉시 비웁니다. 필요하면 일정 시간 후 Destroy Actor로 제거합니다.
      • 성공 경로의 끝에서 Success=True를 반환합니다.
BP_PlayerCharacter (플레이어 캐릭터) 수정
  • Interact 입력에서 Line Trace의 유효한 Hit Actor를 BP_OreVein으로 확인한 뒤 MineResource(Self)를 호출합니다.
  • Success=True인 경우에만 PlayerInventory에 광물 1개를 추가합니다. 예시는 인벤토리가 항상 수용 가능한 단일 플레이어를 전제로 합니다. 용량 제한이 있으면 차감 전에 수용 여부도 검사합니다.

광맥이 수량을 바꾸고 성공한 요청의 자원만 인벤토리에 더합니다

광맥 요청 검사→자기 수량을 3에서 2로 차감→True 반환→인벤토리 1 증가라는 소유자별 상태 전이 과정이다. 실패는 둘 다 유지하며 마지막 1의 고갈도 보존한다.

RESOURCE OWNER · REQUEST VALIDATION · SUCCESS

광맥이 수량을 바꾸고 성공한 요청만 인벤토리에 더합니다

본문의 단일 플레이어·항상 수용 가능한 인벤토리 예제입니다. 자원 수량은 BP_OreVein이 소유하고, 플레이어는 MineResource(Self)의 성공 결과를 받아 인벤토리를 갱신합니다.

광맥 소유자의 검사와 성공 결과에 따른 인벤토리 변경플레이어가 현재 광맥에 MineResource와 요청 플레이어를 전달한다. 광맥은 유효 참조·범위·남은 수량을 검사한다. 성공이면 자기 수량을1줄이고0이면고갈처리를한후True를반환한다. 플레이어는True일때만인벤토리에1을더한다. 검사실패는False를반환하며광맥수량과인벤토리는그대로다. 단일 플레이어·항상 수용 가능한 인벤토리 조건이며 멀티플레이 트랜잭션은 구현하지 않았다.광맥 · ResourceAmount 소유플레이어 · 요청현재 광맥 · Self 전달MineResource요청 수용 가능?유효 참조 · Overlap남은 수량 > 0예광맥 수량 −10이면 고갈 처리Success = TrueTrue 반환플레이어 · 반영인벤토리 +1아니오실패 결과광맥 수량 유지Success = False인벤토리 +0
광맥 소유자의 검사와 성공 결과에 따른 인벤토리 변경플레이어가 현재 광맥에 MineResource와 요청 플레이어를 전달한다. 광맥은 유효 참조·범위·남은 수량을 검사한다. 성공이면 자기 수량을1줄이고0이면고갈처리를한후True를반환한다. 플레이어는True일때만인벤토리에1을더한다. 검사실패는False를반환하며광맥수량과인벤토리는그대로다. 단일 플레이어·항상 수용 가능한 인벤토리 조건이며 멀티플레이 트랜잭션은 구현하지 않았다.광맥 · 수량 소유플레이어 · 요청현재 광맥 · Self 전달MineResource요청 수용 가능?유효 참조 · Overlap남은 수량 > 0예광맥 수량 −10이면 고갈 처리Success = TrueTrue 반환플레이어 · 반영인벤토리 +1아니오실패 결과광맥 수량 유지Success = False인벤토리 +0

유효 요청의 수량 3은 2로 줄고 인벤토리는 1 증가합니다. 마지막 1개에 성공하면 수량 0과 고갈 상태를 확정한 뒤 인벤토리 1을 더합니다. 범위 밖·무효·이미 고갈된 요청에서는 수량과 인벤토리를 모두 유지합니다.

광맥 수량을 바꾸는 책임과 성공 결과를 소비하는 책임을 나눴습니다. 용량 제한이 있으면 차감 전에 수용 여부도 확인하는 설계가 필요합니다. 멀티플레이에서는 서버 상태 변경·복제·RPC 소유권과 실패 처리를 별도로 구현합니다.

이 예의 조건

  • 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
  • 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
관계도의 보충 설명
원 도표의 제목·노드·관계·조건·주석
범위원문
본문·주석광맥이 수량을 바꾸고 성공한 요청의 자원만 인벤토리에 더합니다
관계·조건 설명플레이어가 현재 광맥에 MineResource와 요청 플레이어를 전달한다. 광맥은 유효 참조·범위·남은 수량을 검사한다. 성공이면 자기 수량을 1 줄이고, 0이면 고갈 처리를 한 후 True를 반환한다. 플레이어는 True일 때만 인벤토리에 1을 더한다. 검사에 실패하면 False를 반환하며 광맥 수량과 인벤토리는 그대로다. 단일 플레이어·항상 수용 가능한 인벤토리 조건이며 멀티플레이 트랜잭션은 구현하지 않았다.
노드·연결선 라벨아니요
본문·주석유효 요청의 수량 3은 2로 줄고 인벤토리는 1 증가합니다. 마지막 1개의 채광에 성공하면 수량 0과 고갈 상태를 확정한 뒤 인벤토리 1을 더합니다. 범위 밖·무효·이미 고갈된 요청에서는 수량과 인벤토리를 모두 유지합니다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
요청 검사

광맥 소유자가 채광 요청을 검증한다.

  • 광맥 수량: 3
  • 인벤토리: 이전 값
  • 요청자만 검사하고 자원 소유자를 우회해 차감하지 않는다.
소유자 성공

광맥이 자기 수량을 2로 만들고 True를 반환한다.

  • 광맥: 3→2
  • 반환: True
  • 성공 결과는 실제 차감 뒤에 나온다.
획득 반영

성공 때만 인벤토리에 1을 더한다.

  • 인벤토리 변화: +1
  • 실패 때: 광맥·인벤토리 유지
  • Success=True는 광맥 소유자의 차감 완료를 뜻하므로 인벤토리를 1 늘린다. False는 두 수량을 유지한다. 마지막 1개는 수량 0과 고갈 상태를 확정한 뒤 성공을 반환한다.

광맥이 수량을 바꾸고 성공한 요청의 자원만 인벤토리에 더합니다

광맥 요청 검사→자기 수량을 3에서 2로 차감→True 반환→인벤토리 1 증가라는 소유자별 상태 전이 과정이다. 실패는 둘 다 유지하며 마지막 1의 고갈도 보존한다.

RESOURCE OWNER · REQUEST VALIDATION · SUCCESS

광맥이 수량을 바꾸고 성공한 요청만 인벤토리에 더합니다

본문의 단일 플레이어·항상 수용 가능한 인벤토리 예제입니다. 자원 수량은 BP_OreVein이 소유하고, 플레이어는 MineResource(Self)의 성공 결과를 받아 인벤토리를 갱신합니다.

광맥 소유자의 검사와 성공 결과에 따른 인벤토리 변경플레이어가 현재 광맥에 MineResource와 요청 플레이어를 전달한다. 광맥은 유효 참조·범위·남은 수량을 검사한다. 성공이면 자기 수량을1줄이고0이면고갈처리를한후True를반환한다. 플레이어는True일때만인벤토리에1을더한다. 검사실패는False를반환하며광맥수량과인벤토리는그대로다. 단일 플레이어·항상 수용 가능한 인벤토리 조건이며 멀티플레이 트랜잭션은 구현하지 않았다.광맥 · ResourceAmount 소유플레이어 · 요청현재 광맥 · Self 전달MineResource요청 수용 가능?유효 참조 · Overlap남은 수량 > 0예광맥 수량 −10이면 고갈 처리Success = TrueTrue 반환플레이어 · 반영인벤토리 +1아니오실패 결과광맥 수량 유지Success = False인벤토리 +0
광맥 소유자의 검사와 성공 결과에 따른 인벤토리 변경플레이어가 현재 광맥에 MineResource와 요청 플레이어를 전달한다. 광맥은 유효 참조·범위·남은 수량을 검사한다. 성공이면 자기 수량을1줄이고0이면고갈처리를한후True를반환한다. 플레이어는True일때만인벤토리에1을더한다. 검사실패는False를반환하며광맥수량과인벤토리는그대로다. 단일 플레이어·항상 수용 가능한 인벤토리 조건이며 멀티플레이 트랜잭션은 구현하지 않았다.광맥 · 수량 소유플레이어 · 요청현재 광맥 · Self 전달MineResource요청 수용 가능?유효 참조 · Overlap남은 수량 > 0예광맥 수량 −10이면 고갈 처리Success = TrueTrue 반환플레이어 · 반영인벤토리 +1아니오실패 결과광맥 수량 유지Success = False인벤토리 +0

유효 요청의 수량 3은 2로 줄고 인벤토리는 1 증가합니다. 마지막 1개에 성공하면 수량 0과 고갈 상태를 확정한 뒤 인벤토리 1을 더합니다. 범위 밖·무효·이미 고갈된 요청에서는 수량과 인벤토리를 모두 유지합니다.

광맥 수량을 바꾸는 책임과 성공 결과를 소비하는 책임을 나눴습니다. 용량 제한이 있으면 차감 전에 수용 여부도 확인하는 설계가 필요합니다. 멀티플레이에서는 서버 상태 변경·복제·RPC 소유권과 실패 처리를 별도로 구현합니다.

이 예의 조건

  • 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
  • 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.

관계도의 보충 설명

원 도표의 제목·노드·관계·조건·주석
범위원문
본문·주석광맥이 수량을 바꾸고 성공한 요청의 자원만 인벤토리에 더합니다
관계·조건 설명플레이어가 현재 광맥에 MineResource와 요청 플레이어를 전달한다. 광맥은 유효 참조·범위·남은 수량을 검사한다. 성공이면 자기 수량을 1 줄이고, 0이면 고갈 처리를 한 후 True를 반환한다. 플레이어는 True일 때만 인벤토리에 1을 더한다. 검사에 실패하면 False를 반환하며 광맥 수량과 인벤토리는 그대로다. 단일 플레이어·항상 수용 가능한 인벤토리 조건이며 멀티플레이 트랜잭션은 구현하지 않았다.
노드·연결선 라벨아니요
본문·주석유효 요청의 수량 3은 2로 줄고 인벤토리는 1 증가합니다. 마지막 1개의 채광에 성공하면 수량 0과 고갈 상태를 확정한 뒤 인벤토리 1을 더합니다. 범위 밖·무효·이미 고갈된 요청에서는 수량과 인벤토리를 모두 유지합니다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
요청 검사

광맥 소유자가 채광 요청을 검증한다.

  • 광맥 수량: 3
  • 인벤토리: 이전 값
  • 요청자만 검사하고 자원 소유자를 우회해 차감하지 않는다.
소유자 성공

광맥이 자기 수량을 2로 만들고 True를 반환한다.

  • 광맥: 3→2
  • 반환: True
  • 성공 결과는 실제 차감 뒤에 나온다.
획득 반영

성공 때만 인벤토리에 1을 더한다.

  • 인벤토리 변화: +1
  • 실패 때: 광맥·인벤토리 유지
  • Success=True는 광맥 소유자의 차감 완료를 뜻하므로 인벤토리를 1 늘린다. False는 두 수량을 유지한다. 마지막 1개는 수량 0과 고갈 상태를 확정한 뒤 성공을 반환한다.

환경 변수와 플레이어 행동 연동의 최적화

  • 상태 관리: 개별 광맥의 자원은 광맥에, 공유 날씨는 Manager에 두는 식으로 소유자를 정합니다. 멀티플레이의 GameMode 인스턴스는 서버에만 있으며, 클라이언트가 알아야 할 공유 상태에는 GameState나 복제 액터를 사용합니다.
  • 효율적인 업데이트: Event Tick에서 모든 환경 변수를 매 프레임 업데이트하는 것은 비효율적입니다. Set Timer by Event를 사용하거나, 특정 이벤트(예: 날씨 전환, 플레이어 상호작용) 발생 시에만 업데이트 로직을 실행하도록 합니다.
  • 시각적/청각적 피드백: 환경 변화가 발생할 때 시각적 효과(파티클, 포스트 프로세스)와 청각적 효과(사운드)를 적절히 사용하여 플레이어에게 변화를 명확히 인지시킵니다.
  • 네트워크 레플리케이션: 멀티플레이어 게임에서는 환경 변수의 상태와 그에 따른 오브젝트 변화가 모든 클라이언트에 정확히 동기화되어야 합니다. 액터 복제, 서버에서의 상태 변경, 필요한 변수의 Replicated/RepNotify, RPC의 소유권을 구분해 구현합니다. 변수에 체크하는 것만으로 모든 이벤트와 연출이 자동 복제되지는 않습니다.
  • 아키텍처 설계: 복잡한 상호작용 시스템을 구축하기 전에 전체적인 아키텍처(어떤 블루프린트가 어떤 데이터를 관리하고 어떤 이벤트를 발생시킬지)를 미리 설계하는 것이 중요합니다.

채집 실습에서는 범위 밖 요청, 이미 고갈된 요청, 연속 입력을 테스트하고 실패한 요청이 수량과 인벤토리를 바꾸지 않는지 확인합니다.

확인 문제: 자원 3개·OreCount=0에서 유효 요청 2번, 범위 밖 요청 1번, 다시 유효 요청 2번을 보내면?

처음 두 성공 뒤 광맥은 1개, OreCount는 2입니다. 범위 밖 요청은 두 수량을 그대로 두고, 다음 유효 요청에서 광맥 0·OreCount 3과 고갈 처리를 확정합니다. 마지막 요청은 이미 고갈되어 실패하므로 광맥 0·OreCount 3이 유지됩니다. 실패까지 모두 인벤토리에 더했다면 입력 발생과 성공 결과를 혼동한 것입니다.


환경 변수와 플레이어 행동의 연동은 게임 세계의 깊이를 키우는 고급 기술입니다.

날씨/시간 시스템, 자원 시스템, 상태 변화, 동적 이벤트 트리거를 조합해 플레이어의 선택이 월드 전체에 반영되도록 구성해 보세요.

변화하는 조건에 맞춰 전략을 다시 세우는 재미가 플레이 경험을 크게 끌어올립니다.