본문 바로가기

전체 글

(166)
[언리얼 실습] 65. 에너미 어택 몽타주 재생하기 목차몽타주 재생하기1. 몽타주 재생하기 에너미의 공격을 구현하기 위해서 몽타주를 재생해보려고 한다. 에너미의 헤더파일로 들어가자. virtual void Attack() override;virtual void PlayAttackMontage() override; Attack()함수와 이 Attack() 함수에서 실행할 PlayAttackMontage() 함수를 선언한다. 이제 이 두 함수를 정의하자. Attack() 함수의 경우 추후 기능을 만들겠지만 지금은 단순히 공격 몽타주를 재생하는 역할만 한다.void AEnemy::Attack(){ Super::Attack(); PlayAttackMontage();}  PlayAttackMontage() 함수는 플레이어 캐릭터에 있는 내용 그대로 복사해 붙여 놓..
[언리얼 실습] 64. 에너미에게 무기 쥐어주기 목차에너미에게 무기 쥐어주기충돌 없애기에너미 사망시 무기 없애기1. 에너미에게 무기 쥐어주기 캐릭터에 무기를 쥐어주는 것도 방패를 쥘때랑 비슷하다. 소켓을 만들고 그것에 무기를 달아주면 된다. 다만 한가지 다른 점은 무기는 방패와 달리 실제 상호작용을 할 것이고 그렇기 때문에 단순한 스태틱매시가 아닌 블루프린트 클래스를 부착해주어야 한다. 에너미 헤더파일로 들어가자 UPROPERTY(EditAnywhere)TSubclassOf WeaponClass; 헤더 파일에 선언을 한뒤 이걸 어디서 생성하고 어떻게 부착시켜야 할까? 방패와 달리 무기는 월드에 생성을 한 뒤 부착을 시도할 것이고 월드에 생성을 하기 위해서는 게임이 시작되어야 할 것이다. BeginPlay()에서 생성하고 부착해보자. UWorld* Wo..
[언리얼 실습] 63. 자식 에너미 클래스 만들기 목차자식 에너미 클래스 만들기에너미에게 방패 쥐어주기1. 자식 에너미 클래스 만들기 에너미는 현재 팔라딘 하나만 있지만 추후 더 다양한 에너미가 나올 수 있고 각각의 매시나 애니메이션등은 다를 것이기 때문에 자식 클래스로 만들어 관리하면 편할 것이다.  자식 블루프린트 클래스를 만들자. 이제 자식 클래스도 만들었으니 무기랑 방패를 주어 에너미를 꾸며보자.2. 에너미에게 무기 쥐어주기 무기 종류는 특정 에너미에게 특정 무기를 주어야 할 것이다. 즉 클래스마다 구분이 필요하다. 자식 클래스로 들어가서 매시를 추가해주자.  그리고 매시를 추가하면 된다. 이제 이 방패를 에너미가 들고 있게 해야한다. 그렇게 하기 위해서는 플레이어 캐릭터에게 했던 것처럼 소켓을 추가하고 그곳에 부착해야 할 것이다. 스켈레톤으로 ..
[언리얼 실습] 62. 에너미가 타격을 받으면 플레이어를 추격하기 목차에너미가 피해를 입으면 반응하기1. 에너미가 피해를 입으면 반응하기 에너미가 피해를 입었을때 플레이어가 추격 사거리 안에 있으면 플레이어를 쫒아가게 할 것이다. 에너미의 상태 열거형이 존재하고 이에 따른 반응도 구현하였기 때문에 이를 구현하는 것은 매우 간단한 작업이 될 것이다. float AEnemy::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser){ if (Attributes && HealthBarWidget) { Attributes->ReceiveDamage(DamageAmount); HealthBarWidget->SetHealthPe..
[언리얼 실습] 61. 공격 사거리 안으로 들어오면 공격상태로 만들기 목차공격 상태로 바꾸기1. 공격 상태로 바꾸기 이제 추격(Chasing)을 하다가 거리가 더욱 가까워저 공격 사거리 안으로 들어오면 공격 상태로 바꿔보려고 한다. 이때 공격 기능의 경우는 나중에 좀 더 있다가 추가할 것이다. 가장 먼저 공격 사거리를 정해야할 것이다. 에너미 헤더파일로 들어가자. UPROPERTY(EditAnywhere)double AttackRadius = 150.f; 공격 사거리를 알았으니 이미 존재하는 CheckCombatTarget() 함수에서 캐릭터와의 거리마다 에너미가 할 행동을 지정해주자. void AEnemy::CheckCombatTarget(){ if (!InTargetRange(CombatTarget, CombatRadius)) { CombatTarget = nullp..
[언리얼 실습] 60. 에너미의 순찰, 추격, 공격 상태 구분하기 목차 Enum으로 캐릭터 상태 구분하기 거리가 멀면 다시 순찰하게 하기1. Enum으로 캐릭터 상태 구분하기 에너미에게 열거형으로 상태를 지정해 해당 상태에 맞는 행동을 하게 하려고 한다. 열거형을 모아둔 CharacterType 파일이 있고 이곳에서 새로운 열거형을 만들자. UENUM(BlueprintType)enum class EEnemyState : uint8{ EES_Patrolling UMETA(DisplayName = "Patrolling"), EES_Chasing UMETA(DisplayName = "Chasing"), EES_Attacking UMETA(DisplayName = "Attacking")}; 이제 에너미 클래스에서 이 열거형을 바탕으로 상태를 지정해주자. EEnemyState ..
[언리얼 실습] 59. 에너미가 플레이어 발견시 반응하기 목차Pawn Sensing Component캐릭터 발견시 함수 호출하기1. Pawn Sensing Component 이제 에너미가 플레이어를 발견하면 추적하게 하고 싶다. 에너미가 캐릭터를 보기 위해서는 Pawn Sensing Component가 필요하다. C++에서 이를 만들어보자. UPROPERTY(VisibleAnywhere)class UPawnSensingComponent* PawnSensing; 이것을 이제 실제 생성자에서 만들어주어야 한다. PawnSensing = CreateDefaultSubobject(TEXT("PawnSensing"));PawnSensing->SightRadius = 4000.f;PawnSensing->SetPeripheralVisionAngle(45.f); Vision..
[언리얼 실습] 58. 패트롤 대기 시간 추가하기 목차 타이머 만들기 타이머에 맞춰서 에너미 패트롤 시키기1. 타이머 만들기 타이머를 만들기 위해서는 FTimerHandle 구조체가 필요하다. 타이머핸들은 타이머를 관리하는 데 사용되는 구조체라고 한다. class PRACTICE_API AEnemy : public ACharacter, public IHitInterface{// 생략private:FTimerHandle PatrolTimer; // 타이머 핸들void PatrolTimerFinished(); // 콜백함수} 타이머 핸들과 타이머가 다 되면 실행할 함수를 선언해주었다. 이제 함수를 정의해보자.void AEnemy::PatrolTimerFinished(){ if (EnemyController && PatrolTarget) { FAIMoveR..
[언리얼 실습] 57. 에너미 실제로 패트롤 시키기 목차서론함수 리팩터링하기에너미 패드롤 시키기1. 서론 현재 우리에게는 에너미가 패트롤 할 위치(액터)를 저장할 배열을 가지고 있다. 이를 활용해 에너미가 실제로 패트롤을 하게 구현해보자.  c++에서 이를 구현하기 전에 혹시 까먹을 수도 있으니 배열들을 먼저 채워주었다.2. 함수 리팩터링하기 이제 패드롤 기능을 구현할 것이다. Tick함수에서 구현할 것인데 해당 함수를 한번 봐보자. void AEnemy::Tick(float DeltaTime){ Super::Tick(DeltaTime); if (CombatTarget) { const double DistanceToTarget = (CombatTarget->GetActorLocation() - GetActorLocation()).Length(); if..
[언리얼 실습] 56. 에너미 패트롤 하기. 목차에너미 패트롤 시키기1. 에너미 패트롤 시키기 에너미가 일정 위치를 지속적으로 순찰하는 기능을 만들어 보려고 한다. 패트롤 타겟을 여러개 만들고 이 타켓들을 순찰하게 하고 싶은데 그러기 위해서 이 타켓들을 배열에 담아서 보관해야 한다. C++에서 이 작업을 해보자. 에너미 클래스에 변수를 선언할 것이다. // 현재 순찰중인 타켓UPROPERTY(EditInstanceOnly, Category = "AI Navigation")AActor* PatrolTarget;// 타켓 배열UPROPERTY(EditInstanceOnly, Category = "AI Navigation")TArray PatrolTargets; PatrolTarget은 현재 에너미가 향하고 있는 목표이다. CombatTarget이 nu..