[UE] 몬스터 AI 구현 #1
·
언리얼엔진(UE)
1. 개요이번에는 TPS, FPS 중에 한 장르로 싱글 슈터 게임을 만드는 팀 프로젝트를 진행하게 되었다. 팀 회의를 거치면서 결국은 TPS 장르로 아주 똑같지는 않지만 퍼스트 디센던트와 같은 흐름을 가지는 게임을 만들게 될 것으로 보인다. 루트 슈터라는 장르의 모든 부분을 가져와서 구현하기에는 기간도 길지 않기 때문에 일단은 몬스터, 보스 몬스터를 잡는 플레이어가 존재하는 형태의 간단한 게임이 될 것으로 예상된다. 이번에 내가 맡은 파트는 적AI 부분이다. 아직 배운 내용도 크게 있지 않고 정말 간단한 부분만 배웠기 때문에 어느 정도까지 구현을 할 수 있을지는 모르겠지만, 구현하기 위해 겪게 될 시행착오들과 그 과정들을 정리하면 도움이 될 것 같아 이렇게 정리 글을 쓰는 것을 시작한다.2. 플레이어를 ..
[UE] 슬라이드 애니메이션 개선
·
언리얼엔진(UE)
1. 문제 상황UMG를 활용해 HUD에서 'Game Over!'라는 문구에 슬라이드 애니메이션을 구현하고자 했습니다. 처음의 의도는 화면 밖에서 문구가 떨어지는 슬라이드 형태였으나, 막상 구현하고 결과물을 보니 게임 오버 메뉴가 뜨는 시점에 순간적으로 화면 가운데에 보인 다음에 위에서 떨어지는 애니메이션이 활성화되는 형태가 되어 문제 발생 3~4초 사이에 화면 가운데에 보인 후 슬라이드 애니메이션 활성화2. 원인 분석원인 추론1.화면 가운데에 나타나는 위치가 HUD 상에서 'Game Over!' 문구의 기본 위치에 해당//게임 오버 메뉴 UI 생성if (GameOverMenuWidgetClass){ GameOverMenuWidgetInstance = CreateWidget(this, GameOverMen..
[UE] UMG를 활용한 게임 HUD 및 WidgetComponent를 이용한 HP바
·
언리얼엔진(UE)
1. 개요UMG를 활용한 UI Animation 생성(슬라이드, 플리커링)HP 상태에 따라 게이지가 변화하는 형태의 HP바를 WidgetComponent를 이용해 3D위젯 형태로 생성2-1. HUD(Heads Up Display)기본적인 HUD 구성입니다. 게임 종료 문구, 점수 표시판, 재시작, 메인 메뉴 버튼으로 구성되어 있습니다. 게임 오버 텍스트 블록에 애니메이션을 적용하기 위해 화면 좌측 하단에서 다음 이미지에서 보이는 +Animation 버튼을 클릭합니다.원하는 이름을 입력하고 해당 애니메이션을 클릭한 상태에서 우측 이미지에서 보이는 +Add를 눌러 GameOverText를 선택합니다.위 이미지에서 +버튼을 눌러 Transform, Render Opacity를 각각 생성해 줍니다.Render ..
[UE] 타이머 사용 시 유의 사항과 해결방법
·
언리얼엔진(UE)
1. 문제 개요오늘은 이전에 강의를 들으면서 만들고 있던 간단한 코인 줍기 게임에서 지뢰 아이템과 관련한 로직을 만지는 도중에 문제를 마주했다.게임 시작 시 메뉴와 게임 오버 시 메뉴를 구분해서 구현한 뒤에 각각 시작, 재시작에 해당하는 버튼을 만들고 해당 버튼을 눌렀을 때, 정상적으로 게임이 초기화되어 시작이 되는지를 확인하는 중이었는데, 어떤 방식이든 상관없이 다시 시작을 하는 과정에서 곧장 게임이 종료될뿐만 아니라 에디터까지 함께 종료되는 크래시 현상을 보였다. 어딘가 잘못되었다는 것은 확실했지만, 이전까지 다른 기능들을 구현하고 확인하는 과정에서는 별다른 이상현상을 보이지 않았기에 도대체 뭐가 문제인지 생각해보았다.크래시 문구와 함께 에러와 관련한 문구를 살펴보다 보니 내가 이전에 구현했던 지뢰 ..
[UE] TSubclassOf<>와 TSoftClassPtr<>
·
언리얼엔진(UE)
1. 개요오늘은 아이템 시스템과 게임 흐름 로직을 구현하는 강의를 들으면서 따라해 보는 와중에 저번에도 지나가면서 본 기억이 있는 TSubclassOf 함수를 이용하면서 TSoftClassPtr에 대한 언급이 나왔다. 강의에서 사용한 함수는 TSubclassof를 사용했다. 그 이유인 즉슨 TSoftClassPtr을 사용하려면 로직적으로 추가적인 처리가 필요하기 때문에 간단히 사용 가능한 TSubclassOf를 사용한 것이었다. 그러면서 덧붙인 이야기가 있었는데 TSubclassOf 함수를 사용하면 메모리에 로드가 되기 때문에 메모리에 로드를 하지 않고 사용하려면 TSoftClassPtr을 사용하는 것이 적절하다는 말이었다. 이야기를 듣다 보니 각 함수를 쓰는 것에 장단점이 따르는 것으로 보이는데 앞으로..
[UE] 월드 좌표계와 로컬 좌표계 (World Space, Local Space)
·
언리얼엔진(UE)
1. 개요최근에 폰을 이용해서 캐릭터의 움직임을 구현하게 되었다. 그런데 그 과정에서 AddMovementInput 함수를 쓰지 않고 AddWorldOffset 함수나 AddActorLocalOffset를 이용해서 폰을 움직여야 한다는 제약사항이 있었다. 원래 AddMovementInput을 사용할 때는 연결된 컨트롤러의 입력을 받아서 그대로 방향벡터와 함께 넘겨주기만 하면 되었지만, 처음에 AddActorLocalOffset와 GetActorForwardVector를 사용해서 폰을 이동시키려고 했더니 자꾸 회전한 후에는 원하는 방향으로 움직이지 않고 이상한 움직임이 보여서 애를 먹었다. 뭔가 이상하다 싶어 함수들에 관해 좀더 자세히 찾아보니 월드 좌표계와 로컬 좌표계의 차이를 알지 못했기 때문에 발생한..
[UE] 액터 생애주기(Actor Life Cycle)
·
언리얼엔진(UE)
1. 개요Actor들을 다루는 과정에서 Tick함수나 생성자를 사용할 때, 어떤 것들은 생성자에서 초기화해주는 것이 좋고 어떤 것들은 Tick함수에서는 해서는 안되고 이래저래 제약사항이 있거나 더 나은 방식이 따로 있다는 것들을 알게 되니 아무래도 이러한 것들을 전반적으로 파악하고 있어야 Actor를 다룰 때 조금 더 편할 것이라는 생각이 들었다. 그래서 이러한 함수들의 역할에 직접적인 영향을 주는 액터 생애주기에 대해 알아보았다.2. Actor Life CycleActor가 생성되고, 월드에서 실행되며, 제거될 때까지의 흐름 Actor의 LifeCycle생성 : 생성자(Constructor)C++클래스 객체가 메모리에 생성될 때 단 한 번 호출월드에 등록된 상태가 아니라서 다른 액터나 월드 관련 기능 ..
[UE] Lerp (선형 보간, Linear Interpolation)
·
언리얼엔진(UE)
1. 개요간단하게 비행체의 움직임을 구현하는 과정에서 언리얼 엔진 내장 중력을 이용하지 않고 직접 Pawn에 중력 가속도를 적용하는 로직을 구현해 보았다. 그 과정에서 현실에서처럼 중력 가속도를 적용하려 했더니 비행체를 계속해서 공중으로 날려보낼 수도 없고, 시간이 지날 수록 중력 가속도에 의해 낙하 속도가 너무 빨라져 결국은 일정 구간 위로 나아가지 못하게 되는 상황이 발생했다. 이를 해결하기 위해 다양한 방법을 찾던 도중에 선형 보간에 대한 개념을 찾게 되어 이에 대해 정리해 보았다. 2. Lerp(Linear Interpolation)선형 보간이란?Linear Interpolation(선형 보간)은 두 값 사이를 특정 비율(Alpha 값)에 따라 보간하여 중간 값을 구하는 방법이다특히, UE에서 F..
[UE] Tick, DeltaTime
·
언리얼엔진(UE)
1. 개요Actor를 다루게 되면 가장 처음 접하게 되는 함수인 BeginPlay()와 Tick()을 살펴보는 중에 Tick 함수에서 이동과 같은 로직을 다루게 될 때는 Tick함수의 기본 매개변수로 선언되어 있는 DeltaTime을 다뤄야만 한다. 로직을 구성하면서 생각해 보니 DeltaTime은 이동 로직뿐만 아니라 Tick에서 실행되는 모든 동작 처리에서 중요한 요소이기 때문에 이에 대해 내용 정리를 해보게 되었다.2. Tick과 DeltaTimeTick : 게임이 매 프레임마다 수행하는 반복적인 작업들이 구현되어 있는 함수게임이 실행되는 동안 지속적으로 호출게임의 프레임 레이트에 따라 실행예) FPS=60 ㅡ> 초당 60번 호출, FPS=120 ㅡ> 초당 120번 호출불필요한 Tick까지 활성화하..
[UE] AActor 클래스의 BeginPlay, Tick 함수의 접근 지정자 차이
·
언리얼엔진(UE)
1. 개요C++로 Actor 클래스를 생성해보면 헤더와 소스파일이 기본적인 형태로 제공되는데 이때 코드를 살펴보면 아래 그림과 같이 BeginPlay는 protected에 위치해있고, Tick함수의 경우에는 public에 선언되어 있는 것이 보인다. 당연하게 넘어갈 수도 있는 부분이지만, 널리 사용되는 상용엔진에서 아무런 이유 없이 그런 차별점을 두었을 리가 없다고 생각되어 이에 대해 알아 보았다.2. BeginPlay와 Tick 함수BeginPlay()객체가 처음 생성되고 플레이 시작 시에 한 번만 호출되는 함수AActor의 라이프사이클에 맞추어 자동으로 호출 ㅡ> 외부에서 직접 호출할 필요 X위 두 가지 특징에 의해 BeginPlay는 protected에 선언하여, 상속 받은 클래스에서만 overri..

.menu_toolbar { display: none !important; }