언리얼엔진(UE)
[UE] 몬스터 AI 구현 #4 (몬스터 기본 클래스 구성)
2h1824
2025. 2. 26. 21:54
1. 클래스 전체 구성
- 공통적인 기본적인 구성 요소를 담는 BaseEnemy
ex) HP, Score, 사망 처리 함수 등 - BaseEnemy를 상속하여 서로 다른 유형의 공격을 하는 Melee, Ranged 로 Enemy 분류
2. BaseEnemy
BaseEnemy.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "BaseEnemy.generated.h"
UCLASS()
class STARHUNT_API ABaseEnemy : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
ABaseEnemy();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Score
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Score")
int32 Score;
// Max Health
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Health")
float MaxHealth;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Health")
float Health;
// Get health variables
UFUNCTION(BlueprintPure, Category = "Health")
float GetHealth() const;
UFUNCTION(BlueprintPure, Category = "Health")
float GetMaxHealth() const;
// Healing
UFUNCTION(BlueprintCallable, Category = "Health")
void AddHealth(float Amount);
// Death handling function
UFUNCTION(BlueprintCallable, Category = "Health")
virtual void OnDeath();
// Damage handling function
virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser) override;
public:
// Called every frame
//virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
//virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
BaseEnemy.cpp
// Fill out your copyright notice in the Description page of Project Settings.
// Copyright Epic Games, Inc. All Rights Reserved.
#include "BaseEnemy.h"
#include "EnemyAIController.h"
// Sets default values
ABaseEnemy::ABaseEnemy()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
//PrimaryActorTick.bCanEverTick = true;
AIControllerClass = AEnemyAIController::StaticClass();
AutoPossessAI = EAutoPossessAI::PlacedInWorldOrSpawned;
}
// Called when the game starts or when spawned
void ABaseEnemy::BeginPlay()
{
Super::BeginPlay();
}
float ABaseEnemy::GetHealth() const
{
return Health;
}
float ABaseEnemy::GetMaxHealth() const
{
return MaxHealth;
}
void ABaseEnemy::AddHealth(float Amount)
{
Health = FMath::Clamp(Health + Amount, 0.0f, MaxHealth);
}
void ABaseEnemy::OnDeath()
{
// Deliver Score to Game Instance
Destroy();
}
float ABaseEnemy::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
float ActualDamage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
Health = FMath::Clamp(Health - DamageAmount, 0.0f, MaxHealth);
if (Health <= 0.0f)
{
OnDeath();
}
return ActualDamage;
}
- Health, MaxHealth, Score 등의 공통 변수 및 함수 선언
- 사망 처리를 할때 공통 수행할 동작을 선언 및 정의
- TakeDamage 함수를 override하여 재정의
- AI 컨트롤러 클래스 설정 및 연결
- AI가 캐릭터를 자동 조종 ㅡ> Placed in World or Spawned (월드 배치 or 게임 중 스폰)
3. EnemyAIController
EnemyAIController.h
// Fill out your copyright notice in the Description page of Project Settings.
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "AIController.h"
#include "EnemyAIController.generated.h"
/**
*
*/
UCLASS()
class STARHUNT_API AEnemyAIController : public AAIController
{
GENERATED_BODY()
public:
virtual void OnPossess(APawn* InPawn) override;
virtual void BeginPlay() override;
virtual void OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result) override;
};
EnemyAIController.cpp
// Fill out your copyright notice in the Description page of Project Settings.
// Copyright Epic Games, Inc. All Rights Reserved.
#include "EnemyAIController.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/NavMovementComponent.h"
void AEnemyAIController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
// Use Acceleration when move along path (associated with Animation)
ACharacter* Character = Cast<ACharacter>(InPawn);
if (Character)
{
UCharacterMovementComponent* MovementComp = Character->GetCharacterMovement();
if (MovementComp)
{
MovementComp->bRequestedMoveUseAcceleration=true;
}
}
}
void AEnemyAIController::BeginPlay()
{
Super::BeginPlay();
}
void AEnemyAIController::OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult& Result)
{
Super::OnMoveCompleted(RequestID, Result);
}
- AI가 폰에 Possess 되었을 때 호출되는 함수를 재정의하여 부모 클래스의 원본 함수를 호출
- 추가로 빙의된 캐릭터 클래스의 CharacterMovementComponent의 움직일 때 가속도를 사용하도록 설정
ㅡ> 해당 옵션 체크하지 않을 시 가속도가 반영되지 않아 캐릭터의 애니메이션 오작동 발생 가능성이 있음
4. Health, MaxHealth, Score 변수 값 초기화
MeleeEnemy.cpp
// Fill out your copyright notice in the Description page of Project Settings.
// Copyright Epic Games, Inc. All Rights Reserved.
#include "MeleeEnemy.h"
AMeleeEnemy::AMeleeEnemy()
{
Score = 100;
Health = 500;
MaxHealth = Health;
}
RangedEnemy.cpp
// Fill out your copyright notice in the Description page of Project Settings.
// Copyright Epic Games, Inc. All Rights Reserved.
#include "RangedEnemy.h"
ARangedEnemy::ARangedEnemy()
{
Score = 150;
Health = 300;
MaxHealth = Health;
}
- 실질적으로 사용되는 Enemy 클래스의 생성자에서 변수들의 값 초기화
5. 정리
완료
- 기본적인 설정 완료
예정
- AI가 어떤 행동을 할지 결정하는 BehaviorTree 및 관련 변수가 저장되는 BlackBorad 생성 및 구성
- 그 외 Melee, Ranged Enemy 클래스나 Base에서 필요한 함수 및 변수 생성, 초기화
- HP 바 위젯
- 순찰 및 공격 + 데미지 시스템
참고자료
X