게임 개발 (언리얼 엔진)

UE4 생존게임 제작 - 11 (몬스터 공격 충돌 시스템 수정 및 Camera Shake 제작)

언린이 2020. 11. 11. 23:38

1. 몬스터 공격 충돌 시스템 수정 이유

 

기존의 몬스터 공격 충돌 시스템은 몬스터가 박스 컴포넌트를 가지고 있게하여 몬스터가 공격을 시작할 때, 해당 박스 컴포넌트와 플레이어가 Overlap이 되는지 감지한 후 데미지를 주었습니다.

그런데 이렇게 하면 모든 몬스터들이 Overlap을 감지해야 해서 많은 비용이 들어가게 됩니다. 또한, 몬스터가 공격을 할 때 멈추게 되는데, 그때 플레이어가 뒤로 이동하면 몬스터의 박스 컴포넌트와 플레이어가 Overlap이 되지 않아서 몬스터는 공격 모션을 취하지만 플레이어는 데미지를 받지 않게 됩니다.

이러한 이유 때문에 플레이어와의 Overlap을 감지하는 박스 컴포넌트들을 전부 제거하고 몬스터의 애니메이션에 노티파이를 만들어 주어서 몬스터가 공격 모션을 취하면 무조건 플레이어에게 데미지를 가하는 방식으로 시스템을 수정하였습니다.

 

 

2. 몬스터 공격 충돌 시스템 수정

 

protected:
	ACharacter* m_pTarget;

 

// 타겟 설정
void APredatorAIController::SetTarget(UObject* pTarget)
{
	Blackboard->SetValueAsObject(TEXT("Target"), pTarget);

	if (pTarget)
		m_pTarget = Cast<ACharacter>(pTarget);
	else
		m_pTarget = nullptr;
}

 

기존에 만들어 두었던 Predator AI Controller의 SetTarget 함수에서 블랙보드 데이터를 수정해주는 것 뿐만 아니라 Predator AI Controller가 타겟이 누구인지 알 수 있도록 들고있게 해주었습니다.

 

 

ACharacter* APredatorAIController::GetTarget() const
{
	return m_pTarget;
}

 

그리고 나서 GetTarget 함수를 만들어서 타겟을 반환하도록 해주었습니다.

 

 

 

그 다음 Damage 노티파이를 만들어주었습니다.

해당 노티파이에서 타겟에게 데미지를 줄 것입니다.

 

 

// 공격이 시작할 때 호출되는 노티파이 함수
void UAnimalAnim::AnimNotify_Damage()
{
	AAnimal* pOwner = Cast<AAnimal>(TryGetPawnOwner());

	if (IsValid(pOwner))
	{
		// AI Controller를 받아온다
		APredatorAIController* AI = pOwner->GetController<APredatorAIController>();

		if (IsValid(AI))
		{
			// 타겟 설정
			ACharacter* Target = AI->GetTarget();

			FDamageEvent	DamageEvent;
			Target->TakeDamage(pOwner->GetAttackDamage(), DamageEvent, AI, pOwner);
		}
	}
}

 

노티파이에서 Predator AI Controller를 받아온 뒤, 정의해두었던 GetTarget 함수를 사용하여 타겟을 받아왔습니다.

그리고 나서 타겟의 TakeDamage 함수를 호출하여 데미지를 주었습니다. 인자 중에 GetAttackDamage 함수는 각각의 몬스터의 공격력을 얻어오는 함수입니다.

 

 

 

플레이어가 멀어져도 이미 몬스터가 공격을 시작했기 때문에 체력이 감소하는 모습을 확인할 수 있습니다.

 

 

3. Camera Shake 제작

 

먼저 CameraShake 클래스를 상속받아서 C++ 클래스를 생성하였습니다.

 

 

UHitCameraShake::UHitCameraShake()
{
	// 0.5초 동안 실행
	OscillationDuration = 0.5f;
	
	//Amplitude : 세기, Frequency : 주파수
	LocOscillation.Y.Amplitude = 1.f;
	LocOscillation.Y.Frequency = 100.f;
	LocOscillation.Z.Amplitude = 1.f;
	LocOscillation.Z.Frequency = 100.f;
	
	// true로 해줘야 한번씩만 떨림
	bSingleInstance = true;
}

 

그리고 나서 생성자에서 카메라가 어느 방향으로 어느 정도의 강도로 흔들릴지 설정하였습니다.

 

 

	// Camera Shake 실행
	SurvivorController->ClientPlayCameraShake(UHitCameraShake::StaticClass(), 1.f, ECameraAnimPlaySpace::CameraLocal);

 

마지막으로 플레이어가 공격을 받았을 때 호출되는 TakeDamage 함수에서 Camera Shake를 실행해주었습니다.

이제 플레이어가 공격을 받을 때마다 카메라가 흔들려서 더욱 생동감 넘칠 것입니다.

 

 

다음에 해야할 일

 

인벤토리 UI, 아이템 및 아이템 사용 효과 제작