
사운드발사체가 발사됐을 때와 탱크나 터렛이 죽었을 때의 사운드를 추가해주자.이를 위해 발사체에 발사시 사운드와 히트 사운드, 베이스폰에 데스 사운드 이렇게 총 3개가 필요하다.우선 발사체에서 사운드 변수를 선언해주자.사운드를 위해서 UBaseSound 타입 포인터 변수를 사용하게 된다. 같은 변수를 2개 사용하기에 앞에만 전방선언 해줘도 뒤에 변수는 해줄 필요가 없다.또는 미리 전방선언을 따로 해주는 방법도 있다. 그리고 베이스폰에서도 선언해주자. 이제 언리얼로 돌아가서 각각에 맞는 사운드 파일을 할당해주자.여기서 Launch Sound와 Hit Sound는 같은 걸로 할당해주었다. Death Sound의 경우 탱크와 터렛 각각에 할당해주어야 한다. 이제 사운드를 재생시키는 방법을 알아야 한다.사운드 ..

죽음 파티클이번에는 폰이 죽었을 때의 파티클을 추가해주자.이를 통해 포탑이나 플레이어(탱크)가 죽었을 때 좀 더 실감나는 모습을 보여줄 수 있다.폰에 해당하는 포탑과 탱크 모두에 대해서 구현하기 때문에, 코드 작성은 BasePawn에서 하게된다. 그리고 이번에는 죽는 순간에 파티클을 생성해주는 것이기 때문에 SpawnEmitterAtLocation 함수를 사용하여 파티클을 구현하게 된다.이를 위해 우선 UParticleSystem 타입 포인터 변수를 선언해주자. 그리고 cpp 파일에서 구현하게 되는데 죽음에 관한 내용이므로 전에 작성해뒀던 HandleDestruction 함수에서SpawnEmitterAtLocation 함수를 작성하게 된다. 이제 언리얼로 돌아가서 죽음 파티클을 할당해주자.이는 탱크와 터..

연기 궤적기존 발사체가 발사될 때 추가적으로 연기 궤적이 발사체에 붙어서 발사되도록 해주자.발사체를 따라 연기 궤적이 쭉 나타나야 하므로 발사체의 루트 컴포넌트에 추가적인 컴포넌트를 붙여주게 된다.이 또한 파티클 시스템이므로 우리가 사용할 컴포넌트는 UParticleSystemComponent이다.해당 컴포넌트에는 템플릿이라는 변수가 존재하며, 해당 변수를 통해 언리얼에서 우리가 사용할 파티클을 할당하게 된다.간단하게 Projectile 헤더에서 선언을 해주고 생성자에서 생성해주자.여기서 해당 컴포넌트를 실질적으로 사용하기 때문에 관련 헤더를 cpp내에 선언해줄 필요가 있다. 다음으로 전에 여러번 해봤듯이 CreateDefaultSubobject를 통해 생성해주고, 이를 루트컴포넌트에 붙여주자. 이제 언..

타격 파티클 현재 발사체를 발사할 때 타격효과가 없어서 다소 심심하게 느껴진다. 이를 개선하기 위해 발사체에 대해 타격 파티클을 추가해주자. 파티클은 맨 처음 해당 강의를 위해 다운받은 자료에 기본으로 들어있는 것을 사용한다. 먼저 발사체 클래스에서 UParticleSystem에 대한 변수를 선언해주어야 한다. 컴파일을 하고 언리얼에서 위 파티클을 직접 할당해주자. 이제 할당한 파티클을 발사체가 무언가를 맞히는 순간 스폰함으로서 파티클을 사용하게 된다. 이를 위해 다음과 같은 함수를 사용한다. 해당 함수는 언리얼 공식 문서에서 가져온 내용이나, VScode 에서 해당 함수를 살펴보면 오버로드 된 함수가 추가로 존재하는 것을 볼 수 있다. 우리는 그 중에서 하나를 선택하여 사용할 것이며, 해당 함수는 다음..

게임 오버 UHD 게임 승패 유무에 대해 간단하게 print string으로 표시했었지만, 이제 위젯으로 출력해보록하자. 이를 위해 기존 위젯을 복사하여 게임 승패용 위젯을 하나 만들어주자. 이후 Create Widget을 통해 위젯을 생성하고, 해당 return value에서 Display Text를 얻는 것이 가능하다. 또 Display Text에서 Set Text를 얻는 것이 가능하여 원하는 텍스트를 위젯을 통해 출력이 가능하다. 하지만 우리는 게임 승패 유무를 체크하는 bool 타입 변수를 사용하고 있지 않다. 이를 활용하여 게임 승패에 맞는 텍스트를 출력해줄 필요가 있다. 이때 사용할 수 있는 것이 Select 함수이다. 해당 함수를 통해 인덱스를 받고, 리턴 값 또한 원하는 것으로 조절이 가능..

승패 조건 기본적인 게임의 틀은 완성하였으니, 이제 승패 조건을 설정해주자. 승패 조건은 당연하게도 탱크가 죽으면 진 것이고, 탱크가 살아있고 남은 터렛을 모두 파괴하면 승리이다. 우리는 위젯으로 게임 승패에 대해 출력해줄 것이므로, 전과 같이 BlueprintImplementableEvent를 사용하여 함수를 선언해준다. 승패 유무 체크를 위한 간단한 bool 타입 변수도 가지게 된다. 해당 함수는 어디서 호출되어야 할까. 바로 탱크가 죽는 순간과 타워가 죽는 순간이다. 이는 게임모드에서 ActorDied 함수로 구현을 했었기 때문에 간단하게 바로 파악이 가능하다. 탱크가 죽는 순간은 게임에서 진 것이기 때문에 false의 값을 넘기도록 하였다. 게임에서 이기는 조건인 타워가 모두 죽는 조건은 먼저 체..

카운트 다운 시간 표시하기 이제 print string을 통해 표현했던 것을 위젯으로 나타내볼 것이다. 이를 위해 그래프에서 다시 디자이너로 돌아가서 텍스트 블록에 대해 변수 여부를 체크해주어야 한다. 이러면 이제 해당 텍스트 블록에 대해 float 변수 카운트 다운과 같이 변수로서 접근이 가능해진다. 해당 변수를 끌어와서 Get을 해주고, 해당 핀에서 끌어보면 해당 변수에 대한 Set 함수를 얻을 수 있다. 이제 이를 통해 원하는 텍스트 할당이 가능하고, 실행 핀을 통해서 원하는 숫자로 Switch on Int 함수에서 값 연결이 가능하다. 나머지 값들도 전부 print string을 삭제하고 위와 같이 바꿔주자. 현재 상태에서 출력해보면 숫자 1과 2가 왼쪽으로 치우처서 출력이 된다. 이는 기본 정렬..

카운트다운 타이머 게임이 시작되는 것을 알 수는 있지만, 몇 초 후에 시작되는 지는 정확히 알 수 없다. 이를 위해 얼마나 더 기다려야 하는지 시작 딜레이 즉 카운트 다운를 위젯에 띄워주도록 하자. 우선 기존 위젯 블루프린트에서 우측 상단의 그래프를 눌러주면 이벤트 그래프 창으로 넘어갈 수 있다. 그리고 카운트 다운을 위한 float 변수를 하나 추가해주자. 컴파일을 하고 나면 맨 아래 기본값에서 값 수정이 가능해진다. 이제 이를 이용하여 매틱마다 카운트 다운을 출력해보자. Event Tick에 있는 Delta Time을 이용하여 매 프레임마다 카운트 다운의 값을 감소시켜가며 출력하게 된다. 매 프레임의 시간이 짧으므로, 매우 촘촘한 간격으로 출력되는 모습을 볼 수 있다. 우리가 원하는 건 1, 2, 3..

게임 시작 위젯 게임이 시작되기에 앞서 3초 간의 딜레이를 가지고 탱크가 움직이게 된다. 완성도를 위해 이를 위젯을 이용하여 게임 준비 시간임을 알려주어 보자. 마찬가지로 게임모드에서 해당 함수를 구현하게 된다. 해당 함수는 BlueprintImplementableEvent인데, 이는 C++에서 호출되는 C++ 함수지만 실제 기능은 블루프린트에서 구현한다는 것을 의미한다. 블루프린트에서 다뤄야하므로, private에서 선언은 불가능하다. 이제 기능 자체는 블루프린트에서 다루므로, 단순히 해당 함수가 실행되는 위치만 지정해준다. 이제 언리얼로 돌아가서 위젯 블루 프린트를 작성해주자. 이제 해당 위젯 블루프린트에서 우선 캔버스 패널을 생성해주자. 캔버스 패널을 통해 화면상 원하는 위치에 위젯 요소 배치를 하..

게임 시작 게임을 시작하자마자 바로 플레이 되는 것은 다소 부자연스러울 수 있다. 따라서 게임 시작하기에 앞서 딜레이를 주고, 일정 딜레이를 가진 이후에 본격적인 게임이 시작되도록 해보자. 먼저 딜레이를 위한 변수와, 해당 기능을 위한 함수를 선언해주자. 해당 내용들은 게임모드에 대한 이야기이므로, 게임 모드 클래스에서 선언 및 구현하게 된다. 해당 함수는 게임이 시작할 때 실행되므로 BeginPlay에서 호출하게 된다. 기존 BeginPlay 안에는 Tank와 Tank에 대한 컨트롤러를 얻는 과정이 있다. 해당 기능 또한 우리가 구현할 함수에 합쳐주었다. 먼저 딜레이 시간 동안은 탱크가 움직일 수 없다. 우리는 이를 SetPlayerEnableState 함수를 따로 구현하여 설정을 해준 적이 있다. 여..

사용자 지정 플레이어 컨트롤러 우리는 인풋 비활성화 및 마우스 커서 설정 등 플레이어 컨트롤러에 대해 다루었다. 이를 따로 클래스로 생성하여 직접 기능을 추가해 커스텀하는 것 또한 가능하다. 이어서 블루프린트 클래스 또한 생성해주자. 이제 게임 모드로 가서 방금 만든 컨트롤러를 기본 컨트롤러로 할당해주자. 기본적인 생성 및 할당은 끝났으니, 구현을 해줄 차례이다. 우리가 구현해줄 내용은 플레이어 인풋에 대한 처리와, 마우스 커서에 대한 내용이다. 이를 처리하기 위해 우선 함수를 선언해주자. 해당 불 타입 변수를 토대로 인풋 활성화/비활성화를 체크하고, 이어서 마우스 커서에 대한 것도 할당하게 된다. 인풋에 대한 함수는 EnableInput과 DisableInput 함수를 사용한다. 해당 함수들은 폰에 속..

Pawn 죽음 다루기 Pawn의 죽음을 다루기 위해서는 몇가지 함수가 추가적으로 필요하다. 먼저 죽음을 다루기 위한 함수가 필요하다. 죽음은 폰인 탱크 뿐만이 아니라, 타워도 죽음이 존재하므로 우선 베이스폰에서 해당 함수를 구현해준다. 구체적인 죽음에 대해서는 각 타워 및 탱크에서 다루게 된다. 여기서는 공통적인 부분으로 사운드와 이펙트를 다루게 되는데, 지금은 하지 않으므로 빈 칸으로 냅두고 넘어간다. 이어서 우선 타워에서 해당 함수를 구현해주자. 타워의 경우 간단하게 Destroy를 통해 파괴를 해주면 된다. 이때 베이스폰에서의 사운드와 이펙트 기능을 상속 받기 위해 Super를 사용해준다. 하지만 탱크의 경우는 다소 복잡하다. 우리는 탱크가 죽더라도 탱크의 뷰를 가지고 있는 것을 원한다. 따라서 인..

Game Mode 클래스 대략적인 게임의 형태를 만들었으니, 이제 게임과 관련된 규칙을 만들어 주자. 이를 위해서 Game Mode 클래스를 사용하며, 폰 죽음 및 죽음으로 인한 게임 승패 여부와 같은 것도 해당 클래스를 통해 구현하게 된다. 먼저 C++ 클래스를 통해 생성해주자. C++에서 일단 생성됐으니, 이를 바탕으로 블루프린트 클래스 또한 만들어주자. 기존에 우리가 플레이어 자동 빙의 기능을 이용하여 폰을 세팅했지만, 이제 게임 모드가 존재하기 때문에 여기서 디폴트 폰 클래스를 탱크로 지정해줄 수 있다. 우선 프로젝트 세팅에서 하는 방법이 존재한다. 하지만 우리는 블루 프린트에서 이를 조정하도록 할 것이다. 직전에 만들었던 블루프린트 클래스를 이용하여 디폴트 폰 크래스를 조정할 것이다. 이제 월드..

데미지 적용 이제 실제로 데미지를 적용시켜주자. 데미지는 hit 한 순간에 적용되어야 하므로 우리가 만들었던 OnHit 함수에서 ApplyDamage 함수를 호출하게 된다. 먼저 해당 함수의 인풋 매개 변수를 체크해보자. 데미지 받은 액터, 기본 데미지, 컨트롤러, 데미지 입히는 액터, 데미지 타입을 필요로 하는 것을 알 수 있다. 우선 데미지 받은 액터는 OnHit 함수의 OtherActor에 해당하여 쉽게 할당이 가능하다. 다음으로 기본 데미지는 우리가 줄 데미지 수치로, 헤더에서 따로 선언해주자. 일단 초기 데미지로 50을 선언해주었다. 이제 컨트롤러다. 컨트롤러의 경우 다소 복잡하다. 우선 컨트롤러의 대상은 컴포넌트의 소유주이다. 따라서 GetOwner()를 통해 접근할 수 있다고 생각하지만, 현..

체력 컴포넌트 발사체가 무언가를 맞췄을 때 데미지를 입어야 한다. 따라서 데미지에 앞서 체력을 설정하기 위해 체력 컴포넌트 클래스를 생성해보자. 체력은 트랜스폼이나 어태치 기능이 필요없기에, 액터 컴포넌트 클래스로 생성해주자. 그리고 이어서 최대 체력과 현재 체력을 표시할 변수를 선언해주자. 우선은 체력을 최대 체력에서 시작하고, 데미지를 입으면 감소하게 된다. 따라서 BeginPlay에서 체력을 최대 체력으로 설정해주자. 이제 해당 컴포넌트를 블루프린트 클래스에서 탱크와 터렛에 추가해주자. 최대 체력은 언리얼에서도 편집이 가능하다. 이제 데미지에 대한 내용을 구현해야한다. 우선 언리얼 엔진에는 데미지 기능 또한 존재하며, 모든 액터는 데미지 이벤트를 상속받는다. 여기서 전 강의에서의 OnComponen..