반응형
250x250
Notice
Recent Posts
Recent Comments
Link
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

가끔 보자, 하늘.

언리얼 엔진 5.3 예제로 찍먹하기-04 GamePlay 및 개선 본문

개발 이야기/개발툴 및 기타 이야기

언리얼 엔진 5.3 예제로 찍먹하기-04 GamePlay 및 개선

가온아 2023. 11. 28. 16:31

마지막 찍먹 시간으로 게임 플레이 레벨을 정리해 보겠습니다. 

GameMode에는 BP_GamePlay_GameMode가 등록되어 있습니다. 등록된 내용은 아래와 같습니다. (기본값이 설정된 내용은 별도 언급하지 않겠습니다.)

(* BP의 내용을 볼 때는 ConstructionScript, Event Graph를 중심으로 보면 됩니다. 이곳에서 BP에 등록된 Variables와 Functions를 사용해 필요한 로직을 구현합니다.)

  • Player Controller Class에는 BP_Gameplay_PlayerController가 등록되어 있으며 다음과 같은 역할을 수행합니다.
    • Variables에 등록한 Widget, PlayerHud를 생성합니다. (EventOnPlayerJoin, OC_UpdatePlayerTotal은 로비에서 사용됩니다.)
  • Playter State Class에는 BP_Base_PlayerState가 등록되어 있으며 다음과 같은 역할을 수행합니다.
    • 골드 획득 시 UI 갱신 및 저장
    • 플레이어 정보 저장
  • Default Pawn Class에는 BP_Base_Character가 등록되어 있으며 다음과 같은 역할을 수행합니다.
    • 캐릭터 이동 컨트롤
    • HP 관리 및 죽음 연출
    • HP 관련 UI
    • Pause Event : 남겨진 comment를 보니 unreal의 blueprint로 구현한 멀티플레이에서는 게임 중 실시간 멈춤을 지원하지 않는다고 하네요. 그래서 SetGlobalTimeDilation을 0.0001로 설정한 내용을 확인할 수 있습니다.
    • Passive Stats 처리 : passive 스킬 구현 했으며, 이속 및 자동 회복 두 가지가 구현되어 있습니다.

특별히 Level에 배치된 BP_Game_Manager라는 BP가 있습니다. 게임 로직의 대부분을 구현한 BP로 게임의 진행과 종료, 일반 몹과 보스몹의 소환  등을 담당합니다.

WB_로 시작하는 Widget BP들도 다수 존재합니다.

  • WB_AbilityTile : 스킬 아이콘 및 레벨 표기
  • WB_ChestItems : 게임에서 보물상자를 먹으면 나타나는 Widget. 획득할 수 있는 골드, 스킬 리스트. 
  • WB_ChestMaster : 게임에서 보물상자를 먹으면 먼저 나타나는 Widget.
  • WB_FloatingTextWidget : 데미지, 회복 등에 사용되는 게임 중 뜨는 숫자
  • WB_GameMenu : 'P' 키를 누르면 계속할지 게임을 중단할지에 대한 메뉴가 활성화됩니다. 이때 게임은 Pause되지 않습니다.
  • WB_HealthBar : Player HP Bar
  • WB_LevelUpCard : 스킬 레벨업 시 보여주는 Widget.
  • WB_LevelUpItems : 레벨 업 시 레벨을 올리거나 새로 획득할 스킬을 선택하는 Widget.
  • WB_LevelUpMaster : 이 코드가 WB_LevelUpItems의 구현 코드 가지고 있음.
  • WB_MatchResults : 플레이어가 죽으면 뜨는 화면. 승리/패배 , 킬 수 표기
  • WB_PlayerHud : 게임 중 플레이어 정보 표기 Widget들. 경험치, 레벨, 게임 플레이 시간, 획득한 골드량을 표기합니다.

적 관련 BP들의 기본 구현은 BP_Base_Enemy에서 관리합니다. 그 외 BP_Base_Elite, BP_Emeny_Biohazard, BP_Enemy_Spiker는 모두 BP_Base_Enemy를 상속받고 설정값만 달리합니다.

BP_Base_Enemy의 Viewport를 보면 기본 CapsuleComponent아래 AttackCollisionSphere가 있습니다. AttackCollisionSphere에 플레이어 캐릭터가 들어오면 공격하며, 자신이 데미지를 받을 때는 기본 CapsuleComponent를 사용합니다. Event Graph에서는 다음과 같은 내용이 구현되어 있습니다.

  • 소환 시 Aura를 출력
  • AttackCollisionSphere에서 Overlap 이벤트 발생 시 공격 
  • 공격 받았을 때 메세지 처리와 죽음 처리

그 외 GameplayActors 폴더에는 각종 아이템 BP들이 존재합니다.

지금까지 대략적으로 전체를 한번 살펴 봤습니다. 마지막으로 일부 코드를 수정해 보면서 마무리 하겠습니다.

[시간에 따라 몬스터 HP 증가 ] 

시간이 지나도 몬스터의 능력치는 그대로라 플레이어가 스킬 레벨이 올라가면 너무 쉬워지는군요. 몬스터에게 레벨을 추가하고 레벨에 따라 maxHP가 증가하도록 하여 게임의 난이도를 조금 올려보겠습니다. 

BP_Base_Enemy의 Variables에 CharLevel(integer)이 있습니다. 사용하는 곳이 없는 듯하여 이 값을 그대로 사용하면 되지 않을까 싶네요.그리고 몬스터가 소환될 때 레벨에 따라 5씩 hp가 증가하여 Health값에 더해줍니다. 

그리고 이 레벨을 보이게 몬스터 머리위에 레벨이 보이도록 Text를 추가합니다. Capsule Component를 선택 후 Components의 "Add" 버튼을 누르고 TextRender를 선택합니다. 그리고 Variable Name을 MobLevel이라고 수정합니다. 처음 TextRender를 추가하면 몬스터의 몸 중앙에 위치하게 됩니다. 머리 위쪽에 표시될 수 있도록 조정해 주세요.

이제 MobLevel 컴포넌트에 몬스터의 레벨이 출력되도록 BP를 추가합니다.

다음으로 BP_Game_Manager를 수정해 봅시다. WaveIndex라는 로직이 있는데 이 인덱스가 증가할 때마다 level을 올려주면 너무 힘들어지니 WaveIndex가 3 증가할 때 소환되는 몹의 레벨을 1씩 올리도록 하겠습니다.

이제 게임을 실행해보면 아래와 같이 레벨이 다른 몬스터들이 출현하는 것을 확인할 수 있습니다. 게임이 좀 많이 어려워졌네요. ㄷㄷㄷ

그런데 숫자가 몬스터와 같이 회전하는게 맘에 안드네요. 음... 검색해보니 위젯으로 붙이면 된다고 합니다. 그럼 위젯으로 전환해보죠. 

Widgets 폴더에서 마우스 오른쪽 버튼을 눌러 User Interface -> Widget Blueprint를 선택해 WB_MobLevel이라는 이름으로 Widget을 생성합니다. 그리고 Designer 화면에서 Panel-> Canvas Panel을 선택해 화면에 추가하고, Common -> Text를 선택해 역시 화면에 출력합니다. Text를 선택하고 Details 패널에서 다음과 같이 설정하세요.

  • 이름을 "LevelText"로 수정 후 "isVariable"을 체크합니다. 이렇게 하면 이 컴포넌트를 bp에서 접근 가능한 변수로 자동 등록합니다.
  • Anchors 를 선택 후 화면 중앙으로 중심을 조정 후 position X, Y를 0으로 각각 설정합니다. 
  • Appearance -> Font -> Size를 40으로 수정합니다.

이렇게 하면 cavas 중앙에 텍스트가 출력되는 것까지 확인할 수 있습니다. 이제 Graph화면으로 전환하여 MobLevel (integer) 를 등록합니다. 그리고 Event Construct에 다음과 같이 Node를 설정하세요.

다시 BP_Base_Enemy로 돌아와 기존에 설정했던 TextRender를 삭제하고 관련 BP도 지워주세요. 그리고 Capsule Component아래 Widget을 추가합니다. 추가한 Widget의 Details 창에서 아래와 같이 설정합니다.

  • Space를 Screen으로 설정합니다. (월드 좌표계를 따라가지 않고 화면에 출력되도록 해줍니다.)
  • User Interface -> Widget Class에 WB_MobLevel을 등록합니다.

이제 WB_MobLevel에서 등록한 MobLevel(interger) 변수에 현재 몹의 레벨을 아래와 같이 설정합니다.

이까지 문제없이 진행되었다면 아래와 같이 몬스터에 레벨이 출력되며, 몬스터의 rotate값과 관계없이 모두 화면에 잘 보이는 것을 확인할 수 있습니다.

폰트가 너무 크기도 하고 몹 중앙에 있어서 보기가 영 불편하긴 하네요. 이건 여러분이 직접 수정해 보시면 더 좋겠습니다. 

그럼 이까지... !! 찍먹 잘 해봤습니다. 시간 되면 네트웍 처리 어떻게 하는지 한번 더 살펴봐야겠네요.

끝!!!

반응형