
내비메시를 이용해 AI 이동하기이제 AI가 플레이어를 향해 쫓아오게 만들어보자.AI가 장애물을 피해 플레이어에게 올 경로를 찾을 수 있어야 하는데, 이는 Nav Mesh통해 하게 된다. Nav Mesh는 레벨에서 걸어 다닐 수 있는 공간인 메시로 A* Pathfinding 알고리즘을 사용한다.해당 메시 구역 내 경로를 계획하면 AI가 그 경로를 따라 움직이게 된다.이를 위해 우선 Nav Mesh를 배치해주자. Nav Mesh를 보이도록 하기 위해서는 좌측 상단의 Show 항목에서 Navigation 항목을 활성화 해주어야 한다. 그리고 전에 생성했던 BP_ShooterAIController가 가진 컴포넌트 중에 다음과 같은 컴포넌트가 존재한다. 해당 컴포넌트는 FMesh를 찾아서 우리로 하여금 경로를 생..

AI로 조준하기저번 강의에 이어서 AI에 대해 더 자세하게 알아보자.이번엔 AI 포커스라는 것에 대해 알아보게 된다.AI 캐릭터들이 플레이어 캐릭터를 계속하여 포커스하며 시선을 따라오게 된다. 전 강의에서 생성만 했던 SHooterAIController 클래스에서 구현을 하게 되며, 해당 클래스에 BeginPlay 함수를 만들어주고 해당 함수에서 포커스를 하게 된다. 그리고 사용할 포커스 함수는 다음과 같다.포커스할 대상과 우선순위 값을 받는데, 보통 GamePlay를 기본으로 하므로 따로 건들지 않는다. 포커스할 대상은 우리 플레이어이기에 플레이어 폰을 얻을 필요가 있다.이는 UGameplayStatics에 속한 GetPalyerPawn 함수를 통해 얻을 수 있다. 플레이어 캐릭터는 인덱스가 0이므로..

AI 컨트롤러 생성하고 설정하기현재 적 역할을 위해 세워둔 캐릭터는 아무런 동작없이 가만히 서있기만 한다.생동감 넘치는 적을 표현하기 위해서 AI 기능을 부여할 필요가 있으며, 이번 강의에서 AI 작업을 위한 기본적인 세팅 작업을 복습하게 된다. 먼저 AIController C++ 클래스를 생성하자. 그리고 해당 AIController를 기반으로 한 블루프린트 또한 생성해주자. 그리고 해당 블루프린트 AIController를 우리가 사용할 폰의 디폴트 AIController 클래스로 할당해주자. 이제 플레이를하고 아웃라이너에서 해당 AIController가 검색되는 모습을 볼 수 있다.

이제 사망 애니메이션을 실제 게임플레이랑 연결해보자.전에 선언했던 bool 타입 변수인 Is Dead을 통해 사망 여부를 판별하기 위해 VScode에서 사망 여부를 판별하고 리턴해주는 블루프린트로 노출 가능한 함수를 작성해줄 필요가 있다. 블루프린트에 노출시키기 위해서는 UFUNCTION을 작성해주면 되고, 안에 내용은 BlueprintPure를 작성해주었다.BlueprintPure의 의미는, C++의 const와 유사하지만 더 강력한 의미로 간단하게는 실행핀이 없는 함수를 뜻한다.더 자세히 말하자면 실팽 핀이 없는 함수는 보통 호출하는 대상에 아무 영향을 끼치지 않고 결과만 받는 다는 것을 뜻한다. 예시로 속도를 얻기 위해 사용했던 Get Velcoity 함수 등이 있다.해당 함수 자체는 단지 속도만 ..

불리언 값에 따른 애니메이션 블렌딩무사히 캐릭터가 데미지를 받지만, 체력이 0이 되었음에도 똑같은 모습을 보인다.따라서 체력이 0이 되면 죽게 되는 애니메이션 모션을 추가해보자. 죽는 애니메이션 모션을 추가하기에 앞서서, 우리는 죽었는지 아닌지 체크할 bool 타입 변수가 하나 필요하다.그리고 해당 bool 타입 변수의 값에 따라서 애니메이션을 블렌딩하게 된다.이를 블렌딩해주는 함수는 Blend Poses by bool 함수이다.그리고 죽는 애니메이션도 AnimGraph로 끌어와야 하는데, Death_Forward 애니메이션을 선택하였다. 그리고 Death_Forwar에 대해서는 죽었을 때 한번만 실행되어야 하므로, Loop 옵션을 꺼주었다. 이제 bool 타입 변수 값에 따라 변해야 하므로, 해당 bo..

TakeDamage 함수 오버라이드하기이번에 액터에 데미지를 입히게 되는데, ACtor의 TakeDamage 가상 함수 오버라이드를 통해서 구현해보게 된다.먼저 해당 함수의 원형을 캐릭터 클래스에 선언해주자. 그리고 캐릭터의 최대 체력과 현재 체력을 표시할 변수를 선언해주자. 게임이 시작할 때 현재 체력을 최대 체력으로 설정해주자. 이제 선언했던 TakeDamage 함수를 구현해보자.Super를 통해서 부모 함수의 기능을 가져오고, 리턴값인 적용 데미지 값이 float 값이기에 해당 변수를 선언해서 리턴값을 받아주자. 이후 해당 값을 토대로 현재 체력에서 값을 감소시켜주면 된다.체력이 음수로 가면 안되기에 만약 데미지 수치가 현재 체력보다 높다면 Min 함수를 통해서 더 작은 값을 데미지로 정하여 체력이..

C++ 가상 함수이번에는 잠시 C++ 가상 함수에 대해 알아본다.VScode에서 BeginPlay 함수나 Tick 함수에 virtual과 overide 표시가 붙은 것을 봤을 것이다.이러한 것이 가상 함수를 나타내며, 이번에 이에 대해 더 자세히 알아보는 과정을 가진다.기본적으로 가상메소드는 베이스 클래스에 있는 함수를 오버라이드한다. 먼저 강의에서 사용한 예제를 그대로 캡처해보았다.다음 코드의 결과를 추측해보자. 단순하게 생각해보면 Gun타입 포인터 변수에 대해 한번은 Gun 클래스에 대한 주소접근을, 한번은 Pistol에 대한 주소접근을 해서 할당하였으므로, Gun에 대한 Shoot 함수와 Pistol에 대한 Shoot 함수가 호출된다고 생각할 수 있다.하지만 결과는 오버라이드 되지 않고, 모두 Gu..

액터에 데미지 입히기우리가 만든 총알은 데미지를 입혀야 한다.따라서 이번엔 액터에 데미지를 입히는 방법을 구현해보자.먼저 데미지를 입는 대상이 있어야 하므로, 우리가 만든 캐릭터를 월드에 배치해주자. 다음으로 총알의 데미지를 미리 설정해주자.일단은 10으로 설정을 하였다. 이제 데미지 이벤트를 사용해야 하는데, 먼저 관련 헤더파일을 선언해주자. 데미지 이벤트에 대한 것은 2가지로 FRadialDamage와 FPointDamage이다. FRadialDamage 데미지는 방사형과 같은 데미지를 의미하며, 수류탄 같은 것이 해당될 것이다. FPointDamage 데미지는 단일 데미지를 의미하며, 총알과 같은 것이 해당되기에 우리가 사용할 데미지 이벤트이다. 먼저 우리는 히트된 액터에 대해 알 필요가 있다.만약..

임팩트 효과이제 히트한 위치에 임팩트 효과를 생성해보자.이를 위해 파티클 시스템을 위한 변수를 또 생성해주어야 한다. 이번엔 SpawnEmitterAtLocation 함수를 통해 임팩트를 히트한 위치에 소환해보자.UWorld 값과 파티클 시스템, 히트한 위치, 회전 값을 받게 된다.여기서 회전 값에 대해서만 다소 주의할 필요가 있는데, 필요한 것은 총알이 어느 방향에서 오는 가이다.따라서 발사 방향인 Rotation.Vector()에 -을 붙여준 방향을 할당하게 된다. 이후 언리얼에서 파티클을 할당하고 플레이 해보자. 히트한 위치에도 이제 파티클 이펙트가 있는 것을 볼 수 있다.

라인 트레이싱 By Channel이제 얻은 위치와 회전 을 토대로 라인트레이스를 해볼 차례이다.이를 위해 프로젝트 세팅에서 총알에 대한 트레이스 채널을 생성해주자. 트레이스 채널외에도 오브젝트 채널이 존재하는데,오브젝트 채널은 말그대로 오브젝트 자체에 채널을 달 수 있도록 해주는 것이고 트레이스 채널은 트레이스 라인에 따라 반응을 어떻게 할 지 정하게 되는 것이다. 채널을 만들고 아래 Preset을 통해 기본적인 세팅을 설정할 수 있다. 해당 타입을 더블 클릭하면 위와 같이 프로필이 나오고, 각 트레이스 타입과 오브젝트 타입에 대해 어떻게 반응할 건지 체크하는 것이 가능하다.총알 트레이스 채널을 만들 때 기본적으로 모든 것에 대해 Blocked 되도록 하였기에 여기서 몇 가지 간단하게 설정을 바꿔준다.N..

플레이어 뷰포인트이번 강의에서는 플레이어의 관점에서 사물을 보는 방법을 배우게 된다.주 목적은 뷰포트의 위치와 회전이 우리가 기대하는 것과 일치하는 지 확인하여 만약 레이트레이싱을 할 때 제대로 사물을 가리키게 되는지 체크하는 것이다.이를 위해 디버그 카메라를 그려보고 해당 디버그 카메라가 어떻게 그려지는 지 체크해보자.DrawDebugCamera 함수를 통해 작성하며, 인자로는 UWorld(), 위치, 회전, 각도, 스케일, 색깔, 지속 여부를 넣어준다. 이를 컴파일하고 마우스 좌클릭을 통해 카메라가 어떻게 찍히는 지 체크해보자. 위 사진과 같이 마우스 좌클릭시 카메라의 방향이 우리가 바라보는 방향과 다른 것을 알 수 있다.따라서 우리는 플레이어의 뷰포트 값으로 적용시켜줄 필요가 있다.플레이어 뷰포인트..

파티클 이펙트 스포닝하기 (spawning)지금은 마우스 좌클릭을 하면 로그 메시지만 출력되는 상태이다.이번엔 총을 발사했을 때 나오는 파티클 이펙트를 스포닝되도록 해보자. 우선 파티클 이펙트가 어디서 스포닝될지 확인해보자.원본 Rifle 파일을 들어가보면 확인이 가능하다. 해당 위치를 참고하여 파티클 이펙트를 스폰하게 되며, 이때 사용하는 함수는 SpawnEmitterAttached 함수이다.해당 함수는 UGameplayStatics에 속한 함수이기에 해당 헤더파일을 선언해줄 필요가 있다.또 인자로 파티클 시스템, 붙을 대상 컴포넌트, 붙을 곳의 이름을 받게 된다.파티클 시스템은 따로 헤더에서 선언하고 언리얼에서 할당하도록 해준다. 이제 언리얼에서 원하는 파티클을 할당해주자. 이제 플레이를 해보면 마..

사격 아키텍처총을 만들었으니 이제 총을 직접 사용하는 방법을 알아야 한다.일단은 마우스 버튼을 누르거나 트리거링을 하면 로그 메시지가 출력되도록 해보자 이를 위해서 우선 Gun 클래스에서 트리거 함수를 작성한다.트리거 함수에는 로그 메시지를 작성하는 내용을 넣어준다. 해당 함수는 인게임에서 마우스 좌클릭을 하면 동작해야 할 것이다.이를 위해 마우스 좌클릭에 대한 액션 매핑을 작성할 필요가 있다.또한 이에 대한 함수도 작성해야 할 것 이다. 우선 함수의 경우 캐릭터 클래스에 이미 Gun에 대한 포인터가 있으므로 해당 값을 통해 PullTriger 함수를 호출해준다. 이제 프로젝트 세팅으로 돌아가서 액션 매핑을 할당해주자. 이후 바인딩 작업도 예전과 같이 해주자. 이제 컴파일을 하고 플레이를 하면서 좌클릭을..

소켓을 통해 메시에 부착하기만든 총을 부착하기 위해서는 기존에 있던 총을 제거하거나 안보이도록 감추는 작업을 해주어야 한다.우선 총이 스켈레톤 메시의 어느 부분에 해당하는지 체크해보자. 이제 해당 메시를 C++ 에서 잡아주는 작업을 해보자.GetMesh() 함수를 통해 해당 메시를 얻는 것이 가능하다. 이후 얻은 메시를 감춰주어야 하는데, 이는 HideBoneByName 함수로 가능하다.해당 함수는 감출 대상의 이름과, EphysBodyOp 이라는 변수를 받는다.PBO_None을 작성함으로서 디폴트값 표시가 가능하다. 기존 weapon_r의 위치를 사용하기 위해 해당 위치에 소켓을 생성해주자.해당 소켓은 끼워 넣을 수 있는 지점을 나타내게 된다. 이제 해당 메시를 생성한 소켓 위치에 붙여주는 작업을 해야..

런타임에 액터 스포닝하기(spawning)저번에 만든 총을 이제 캐릭터에 연동할 차례이다.이를 위해 우선 런타임 동안에 소총을 스포닝하는 방법을 알아보자. 액터 스폰에 대해서는 UWorld에 속한 SpawnActor 함수를 통해 스폰하게 된다.총은 게임이 시작되자마자 캐릭터가 가지고 있어야 하므로 BeginPlay에서 해당 함수를 작성하게 된다.해당 함수는 템플릿 함수이므로 우리가 사용할 총의 타입인 AGun을 넣어준다.다음으로 인수를 받는데, 인수는 클래스로 받는 것이 가능하다. (UClass 타입) 기본적으로 우리는 C++에서 스폰 작업을 하지만, 여기서 해당 Gun의 블루프린트 하위를 스폰하게 된다.이를 위해 블루프린트에 후킹할 방법을 알아야한다.C++에서 직접 후킹하는 것은 어려우므로 다른 방법을..