UI를 사용하려면 우선 Build.cs에 UMG를 추가한다.
해당 코드를 추가한다.
LoseScreenClass는 TSubclassOf LoseScreenClass; 이고,
BP로 PlayerController를 만들었으므로, Widget을 설정한다.
GameMode를 위처럼 수정한다.
EndGame이라는 사용자 정의 함수를 생성,
HasEnded는 Controller를 종료시키는 함수라고 하였다.
게임이 끝났다는 것은, 모든 Controller가 종료되는 것이므로,
템플릿과 이터레이터문으로 for문을 돌며 게임 속 모든 Controller를 받아오게 된다.
그리고 HasEnded로 끝낸다.
Player가 이겼는데, 받아온 Controller도 Player라면,
bIsWinner를 true로 설정한다.
즉, EndGame의 매개변수가 true로 들어오고,
PlayerController가 맞다면, 해당 Controller는 winner에 맞게
승자로 친다.
하지만 다른 Controller들은 패자로 친다.
그 반대로 false로 들어오는 경우에는
AI Controller가 승자가 된다.
추가
AIController에는 일반적인 GameHasEnded가 실행되는 것이고,
PlayerController에만 사용자 정의함수로 Super::를 사용하여 구현하였다.
따라서 Player가 죽은 경우에만 Timer가 실행된다.
종료도 안되고 Focus도 안되는 것 같은데..?
음.. HasEnded가 뭘까
적들이 모두 죽으면 승리로 하고 싶다.
이를 위한 가장 쉬운 방법은 남아있는 적의 수를 세고 없다면 승리로 치는 것이다.
AI가 죽더라도 동기화가 제대로 되지 않을 수 있기 때문에
한 AI가 죽을 때마다 AI의 수를 센다.
Character에 정의된 IsDead를 AIController에 굳이 가져와서 쓴다.
그 이유는 주석에 적어두었다.
위처럼 작성하였다.
PullTrigger의 크기가 커서
작은 함수들로 리팩토링을 한다고 한다.
굳이? 싶지만, 재사용과 관리를 위해 진행한다.
그냥 기능에 맞게 재구성하였다.
맥락에서 최종적으로 특정 값을 구하기 위한 코드를 하나의 함수로 뺀다.
그게 Linetrace의 Hit이었고,
ShootDirection도 중간에 구하도록 주변에 있기 때문에,
같이 하나의 함수로 받는다.
받는 것은 &로 받아서 return을 굳이 하지 않고도 값을 갖도록 하였고,
리턴값을 bool로 또 두어서 기능을 하도록 했다.
추가로 AController를 계산을 또 하는 것보다
함수로 만들어두었다.
끝
처음으로 Unreal Engine에 Sound를 넣어본다.
Sound를 추가하는 법은, Effect를 추가하는 법과 유사하다.
Sound가 발생하는 위치를 총구로 둔다.
Sound는 SoundBase, SoundWave, USoundCue가 있는데
SoundWave는 단일 사운드, USoundCue는 조합한 사운드를 의미.
SoundBase를 사용하면 둘 다 된다.
그래서 SoundBase를 일반적으로 사용한다.
이것도 유사하다고 볼 수 있다.
즉 Attached와 Location방식 둘 다 Effect와 유사하다.
FPS게임에서 총소리는 여러개를 둔다. 질리기 때문이다.
기본적으로 Animation Graph와 비슷하다.
노드를 연결한다.
Branch를 이용해서 물체마다 다른 소리를 내기도 한다.
위처럼 만들어본다. 총을 쏠 때마다 랜덤 소리가 나도록 한다.
즉 한 사이클을 모두 랜덤으로 출력하지 않고,
정말 무작위로 출력하기에 방금 전에 나왔던게 또 나올 수가 있다.
지금 사용한 예제는 그냥 전체적으로 pitch를 조절하였다.
그렇게 생성한 Cue를 SoundBase 변수에 직접 장착한다.
잘 된다.
게임에서 Sound가 중요하고, 특히 FPS는 더더욱 중요한데,
거리에 따라, 그리고 왼쪽 오른쪽 방향에 따라 Sound를 출력할 것이다.
SoundCue에 해당 기능이 존재한다.
Attenuation이라는 기능.
Override~하면 설정들이 해제되고 여러 기능을 사용할 수 있다.
하지만 이번 방법에서는 Setting값을 저장하고 사용하고 싶어서
위처럼 SoundAttenuation을 생성한다.
멀리 떨어진 것에 대한 볼륨 설정.
그리고 공간, 방향에 대한 설정.
2개를 한 번에 처리할 수 있다는 것이다.
다른 설정은 그냥 사용하는게 일반적이고,
위의 설정을 주로 수정한다.
위처럼 설정하면, 반경 4m내에선 최대의 소리로 들리고,
멀어지면 멀어질수록 줄었다가.
36m 밖의 소리는 아예 크기가 0인 상태가 된다.
기본적으로 Panning설정을 하면, 좌우가 구분된다.
하지만 Binarual설정을 하면, 좌우와 위아래까지 되는데,
플러그인을 설정해야만하고, 헤드셋을 착용해야 느낄 수 있다.
따라서 이것도 그냥 기본값을 쓴다.
3D Streo Spread는 공간감이 너무 적다면 늘리고,
많다면 줄이는 방식을 사용하는데, 그냥 기본값.
어찌저찌 설정을 마치면 해당 파일을 다른 Cue의 설정으로
그대로 사용할 수 있다. 😃
게임테스트시에,
위의 방법으로 테스트할 수 있다.
조금 부자연스럽긴해도 확실히 공간감이 생겼다.
역시 FPS에선 소리가 매우 중요한 것 같다.
간단하다 TEXT에 + 를 추가하고 색을 입혔다.
플레이어 컨트롤러에 위젯을 추가한다.
정확히 크로스헤어에 맞게 공격되는 모습.
PlayerController의 GameHasEnded가 실행되면,
Crosshair를 지운다.
BlueprintPure노드의 기능을 위처럼 정의한다.
Character로부터 현재 체력 %를 반환한다.
HP Bar의 Binding으로 위처럼 설정한다.
해당 UI를 소유하고 있는 PlayerPawn을 가져와서
멤버함수를 접근하고 사용
잘 적용되는 모습.
BP_Player를 상속받는 BP를 생성하고,
Mesh와 HP값을 수정한다.
GameMode의 기본 Pawn을 바꾼다.
정상적으로 바뀐 모습.
어짜피 내부적으로 Character의 기능들만 사용하고,
BP는 단순히 변수값만 바꾸어 사용할 수 있는 껍데기
정확히 말해서
내부 로직들은 Character에 구현하고,Mesh나 Sound나 Effect나 각종 변수들은
BP에서 설정가능하도록 생성한다면,해당 CharacterCPP를 상속받는 BP를 마음껏 생성하고,
BP마다 커스터마이징하여 사용할 수 있게 되는 것이다.