자기개발/UE5

[UE5] 1. 돌 캐기

KGW2027 2023. 1. 12. 21:12
728x90
반응형

만들고자 하는 것

 


 작동 순서

  1. 플레이어가 캘 수 있는 돌에 다가가면 F를 눌러 채광을 시작하라는 텍스트가 나옴.
  2. F를 누르면 돌을 캐는 애니메이션과 함께 진행도를 나타내는 Progress Bar가 나와서 상황을 알려줌.
  3. 채광이 완료되면 애니메이션 종료, 광물 Actor도 제거한다.

 


1. 플레이어가 캘 수 있는 돌에 다가가면 F를 눌러 채광을 시작하라는 텍스트가 나옴.

 

 3인칭이기 때문에, Raycast(Line Trace)를 이용해 캐려는 광물을 추적하면 조작이 너무 어려워진다.

그래서 광물과의 거리가 일정 거리 내로 진입하면 그 광물을 채광할 수 있는 상태로 만드는 방식을 이용했다.

이 방식을 구현하는 방법은 일반적으로 HIt없이 Overlap만 작동하는 충돌체(Collider)를 만들어서

Overlap이 됐는가 안됐는가를 판단하는 방식을 이용한다.

 

 이 때, Overlap이벤트가 발생했을 때, 그 광물이 채광가능하다는 사실을 알려면 어디서 코드를 실행해야 작동할까?

정답은 당연하게도 둘 다 가능하다이다.

근데, 플레이어의 경우 계속 이동하는 동적인 액터기 때문에, 움직이면서 만날 모든 액터들에 연산을 수행하게된다.

이는 최적화에서 안좋을 수 있으므로, 정적인 액터인 광물에서 구현하는것이 맞다고 판단했다.

 

"BOX" 라는 이름의 광물을 캘 수 있는 거리를 나타내는 Collider에 다른 액터가 Overlap되면,

해당 액터가 Player Tag를 가지고 있는지 확인한 후, 가지고 있다면 Player 로 Cast한뒤 이 광물을 캘 수 있다는 사실을 전달한다. (Interaction Gemstone)

 

 

 이제, 광물에 접근했다는 사실은 알 수 있다.

그렇다면 F를 눌러 채광하라는 텍스트를 표시해야한다. 이는 User Widget을 만들어서 구현하면된다.

 이것은 BPW_Mining이다.

채광 진행도를 알려주는 ProgressBar와 채광을 하기 위해 어떤 키를 눌러야하는지를 알려주는 Text만 존재한다.

텍스트에는 어떤 키를 눌러 채광을 시작할 수 있는 지를 표시해야하고,

여기서는 그냥 F로 고정되어 있으므로 그대로 작성해도 되지만, 사용자의 Input Setting을 읽어서 표시하도록 해보자.

 

 먼저 이를 표시할 텍스트의 Content를 바인딩해준다.

이러면 이 Text의 Content는 GetText 함수의 반환값에 의존하게 된다.

 

 다음과 같은 코드를 통해 UI Owner의 InputSetting에서 Mining 키를 가져온 뒤, 이를 반환해준다.

그러면 위의 예제와 같이 Press "(Mining Key)" to Start Mining. 이 출력되게 된다.

함수에서 이 Exec 연결(흰색 연결)없이 실행하는 법은 함수를 선택한 뒤 Pure를 체크하면 된다.

 

 자, 그러면 텍스트 설정까지 끝났으나 예제를 보면 남은 것이 하나 있다.

텍스트가 계속 나타난 상태로 유지되는 것이 아니라, 원래 없다가 광물 근처로 가면 아래에서 천천히 올라온다.

이것 역시 User Widget에서 제공하는 애니메이션을 사용하면 된다.

 

 좌측 하단을 통해 볼 수 있는 애니메이션 시퀀서에서 텍스트(Alert InteractionDisplay)의 표시를 위한 애니메이션을 만들어준다.

처음하면 조작이 좀 헷갈릴 수 있는데,

먼저, 이동과 투명도를 만들 것이므로 Transform과 Render Opacity에 대한 레이어?를 만들어준다.

그리고 초기 상태에 대한 정보를 0프레임에 레이어 보면 화살표 가운데에 원모양 버튼이 있는데 그것을 눌러서 정보를 저장한다.

이후, 원하는 시간 뒤에 프레임을 삽입한 뒤, 직접 텍스트를 내리는게 아니라, 트랜스폼>이동>Y의 오른쪽을 보면 회색으로 0.0같은 숫자가 있는데, 이걸 수정해줘야한다. 기존 정보가 담긴 프레임에서 상대적으로 움직인다.

직접 움직인 후에 프레임을 만들면 작동하는가는 잘 모르겠는데, 저번에 이걸로 하루종일 왜 안되지... 하고 씨름했던 적이 있어서 그냥 직접 수치조정을 하고있다.

 

아무튼, 이를 통해 애니메이션을 만들었는데, 나올때 혹은 사라질때 하나만 만들면,

반대쪽은 역재생을 통해 구현할 수 있으므로, 1개만 만들면 된다.

 

 재생하는 부분의 블루프린트다.

현재 작동 상태를 저장하고, XOR를 이용해 모드가 달라진 경우에만 작동하게 했는데,

Display Mode가 True인 상태에서 다음에 True가 한번 더 오면 나타나는 애니메이션이 한번 더 발생할 수 있기 때문에,

모드가 바뀐경우에만 애니메이션을 작동하게 해야 중복작동하는 경우가 없다.

 

여기까지 1번 과정은 완료..

 


2. F를 누르면 돌을 캐는 애니메이션과 함께 진행도를 나타내는 Progress Bar가 나와서 상황을 알려줌.

 F라고 되어있지만, 일단 "Mining"키를 누르면이다.

그러면 일단 Mining키를 Binding해야 하므로 프로젝트 세팅>입력에 들어가 액션 매핑에서 Mining을 추가, 키를 F로 설정한다.

그리고, 플레이어 블루프린트에 들어가 Mining을 누르면 광질을 시작/중단 하는 코드를 추가한다.

 

 만약, IsMining(채광중인가?)가 True라면 채광을 중단,

False라면 TargetGemstone(채광할 수 있는 광물 Array)에 광물이 존재하면, 채광을 시작한다.

StartMining 함수가 하는 일은 2가지인데,

 1. 애니메이션 작동

 2. 플레이어 캐릭터가 광물을 바라보도록 변경

이다.

 

먼저 애니메이션은 기본 캐릭터의 Anim BP인 ABP_Manny에 애니메이션을 추가했다.

 기본 애니메이션 작동의 마지막 부분에서 IsMining 값에 따라 원래 Pose와 광질 Pose중에 골라서 작동하도록 했다.

 

 또한, 플레이어가 가지고 있는 곡괭이의 Visibility도 보이는 상태로 수정한다.

이러면 광질 애니메이션 작동 + 곡괭이 표시가 작동한다.

 

플레이어 캐릭터가 광물을 바라보도록 하는 방법은

이렇게 플레이어의 위치와 캐는 광물의 위치를 가지고 Find Look at Rotation을 이용한 뒤, Yaw값만 적용시켰다.

 

이제 애니메이션 부분은 마무리가 됬으니, Progress Bar를 건드려야하는데, 그럴려면 일단 광질 진행도에 대한 값이 필요하다. 이 부분은 Tick을 이용해 Delta Time을 더해가며 진행했다.

 

 W Interaction은 이제 위에서 텍스트와 ProgressBar가 있는 UI 블루프린트를 담은 변수다.

이 변수가 Valid하고, 현재 채광중이라면, Mining Progress를 DeltaTime*0.12(채광 속도) 만큼 더해주고,

UI의 SetMiningStatus에 Progress를 전달한다. 그리고 이 Progress가 1(100%)에 도달하면 광질을 중단한다.

 

 UI의 SetMiningStatus는 다음과 같은데,

진행률을 표시하는 ProgressBar의 Visibility는 IsMining에 바인딩되어있고, Percent는 MiningProgress에 바인딩되어있다.

그래서 이 함수를 통해, 진행률이 0 < x < 1 이면 Progress바를 표시하면서, 진행률도 갱신하게 된다.

 

플레이어에게 있는 CancelMining은 간단하게, 채광을 시작하면서 수정했던 변수들을 다시 채광 시작 이전으로 돌려놓는 것이다. 예를 들어 곡괭이를 다시 숨기고, ABP_Manny의 IsMining을 false로 만드는 등이다.

 

 추가로, 곡괭이를 내려찍는 순간에 돌을 캐는듯한 소리를 내게 하는 방법은 2가지가 있는데,

하나는 애니메이션 Notify를 이용 하는 방법이다.

이렇게 애니메이션에 노티파이를 추가해서, 애니메이션 블루프린트에서 Notify가 작동할 때, SoundQue를 재생하면된다.

 

 또는, 곡괭이에 Collider를 추가해서 hit할 때 소리가 재생되게 하던가 하는 방법이 있다.

이외에 더 정확한 타이밍에 효율적으로 재생하는 방법이 있는지는 잘 모르겠다. 아마 더 좋은 방법이 있을 것이다.

이 두가지 방법은 너무 원시적인 방법인 것같아서..

 

 3번은 애니메이션 종료 및 액터 제거인데,

애니메이션 종료는 위에서 적은 것처럼 CancelMining을 실행하고,

액테 제거는 TargetGemstone[0].Destory()를 작동하면 끝이므로 설명할 것이 없다.

 


 게임 개발은 단순히 기능 구현뿐만 아니라 성능 최적화가 중요한 요소라고 생각하는데,

최적화는 진짜 경험으로 배우는게 제일 빠르다고 생각해서 이것저것 계속 만들어보고 있다.

만들면서 맨날, 이렇게 작동하는게 1,000개, 10,000개가 있으면 렉이 걸리지 않을까.. 라는 생각을 하지만

한 번 'More Better'에 신경을 쓰기 시작하면 진짜 밑도 끝도 없이 파고 내려가는 일이 잦기 때문에 일단 기능 구현에 집중해서 해보고 있다.

728x90
반응형

'자기개발 > UE5' 카테고리의 다른 글

[UE5] 3. RPC를 공부하며..  (0) 2023.02.24
[UE5.1] 위젯과 ChatGPT  (0) 2023.02.22
[UE5] 2. Mesh Outline  (0) 2023.02.07