[UE5] ๐Ÿš€ Project Galaga (8)

Singery00ยท2024๋…„ 5์›” 21์ผ
0

Project Galaga

๋ชฉ๋ก ๋ณด๊ธฐ
8/15
post-thumbnail

๊ฐœ์š”

๐Ÿš€ Project Galaga ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

Unreal C++๊ณผ ๊ฒŒ์ž„์ˆ˜ํ•™์„ ์ ‘๋ชฉํ•ด์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

2024.05.04 ~ 2024.05.21์˜ ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„์œผ๋กœ, ์ด 17์ผ ๋™์•ˆ ๊ฐœ๋ฐœ์„ ์™„๋ฃŒํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ฑฐ์ฐฝํ•˜๊ฒŒ ์‹œ์ž‘ํ•œ ํ”„๋กœ์ ํŠธ๋ณด๋‹จ ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๊ฒƒ๋“ค์„ ์ข…ํ•ฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•ด์„œ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค์–ด ๋‚ด๋ณด๊ฒ ๋‹ค๋Š” ๋งˆ์Œ์œผ๋กœ ์™„์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น ์‹œ๋ฆฌ์ฆˆ์—๋Š” ๊ฐœ๋ฐœ ์ผ์ง€๋ฅผ ์ •๋ฆฌํ•˜๋ฉฐ, ๊ฐœ๋ฐœ ๋‚ด์šฉ์— ๋Œ€ํ•œ ์„ค๋ช…๊ณผ ์ด์Šˆ๋ฅผ ์ •๋ฆฌํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๐Ÿš€ Project Galaga Github Repository


๋ณธ๋ก 


ํ”ผ๊ฒฉ ์‹œ์Šคํ…œ

Project Galaga์—์„œ ํ”Œ๋ ˆ์ด์–ด๋Š” 2๊ฐ€์ง€์˜ ํ”ผ๊ฒฉ ์กฐ๊ฑด์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

  1. ์ ๊ธฐ์™€ ์ถฉ๋Œํ•˜์˜€์„ ๋•Œ
  2. ์ ์˜ ๊ณต๊ฒฉ ์š”์†Œ (์ด์•Œ, ๋ ˆ์ด์ €)์— ์ถฉ๋Œํ•˜์˜€์„ ๋•Œ

์œ„ ์ด๋ฒคํŠธ๋“ค์€ Overlap Event๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ถฉ๋Œ๋œ ์•กํ„ฐ๊ฐ€ 'Player' ํƒœ๊ทธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์„ ์‹œ์— Apply Damage()์™€ Take Damage()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ”ผ๊ฒฉ ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ ๋“ค๋„ ๋™์ผํ•œ ๋กœ์ง์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.


Collision ์„ค์ •

ํ”Œ๋ ˆ์ด์–ด๋Š” BlockAll ํ”„๋ฆฌ์…‹์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
์ ๊ณผ ์ด์•Œ์€ OverlapAll ํ”„๋ฆฌ์…‹์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

ํ”Œ๋ ˆ์ด์–ด์˜ ์ด์•Œ์€ OverlapAll์ธ ์ ์—๊ฒŒ Overlap Event๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด BlockAll ํ”„๋ฆฌ์…‹์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.


BeginOverlap()

์ด์•Œ์˜ Overlap Event๋ฅผ ์œ„ํ•ด์„œ OnComponentBeginOverlap() ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

// ๋ฐ”์ธ๋”ฉ
BulletBodyCollision->OnComponentBeginOverlap.AddDynamic(this, &AEnemyBullet::OnComponentBeginOverlap);

ApplyDamage()

์•ž์„œ ์„ค๋ช…ํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ด ์ถฉ๋Œํ•œ ๊ฐ์ฒด๊ฐ€ 'Player' ํƒœ๊ทธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ApplyDamage()๋ฅผ ํ˜ธ์ถœํ•˜์˜€์Šต๋‹ˆ๋‹ค.

// ๊ตฌํ˜„๋ถ€
void AEnemyBullet::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (OtherActor->ActorHasTag("Player") && IsActive())
	{
		Deactivate();
		UGameplayStatics::ApplyDamage(OtherActor, 1, NULL, NULL, NULL);
	}
}

TakeDamage()

ํ”ผ๊ฒฉ ๋Œ€์ƒ์—๊ฒ TakeDamage() ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

์ฒด๋ ฅ์„ ๊ฐ์†Œ ์‹œํ‚ค๊ณ , Hp๊ฐ€ 0์ดํ•˜๊ฐ€ ๋˜์—ˆ๋‹ค๋ฉด ํŒŒ๊ดด์— ๊ด€๋ จ๋œ ๋‚ด์šฉ์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

float AMyPlayer::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
	float damage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);

	if (!isHit)
	{
		isHit = true;

		this->PlayerHp -= damage;
		if (PlayerMove)
		{
			DestroyingPlayer();
		}


		if (PlayerHp <= 0)
		{
			PlayerMove->DestroyComponent();

			PlayerBodyCollision->SetSimulatePhysics(true);
			PlayerBodyCollision->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
			PlayerBodyCollision->SetMassOverrideInKg();

			FVector ImpulseDirection = FVector(FMath::RandRange(-1.0f, 1.0f), FMath::RandRange(-1.0f, 1.0f), -1);
			ImpulseDirection.Normalize();

			PlayerBodyCollision->AddForce(ImpulseDirection * 100000.0f);
		}

		FTimerHandle isHitTime;
		GetWorldTimerManager().SetTimer(isHitTime, this, &AMyPlayer::setCanHit,2.0f,false);
	}


	return 0.0f;
}

๋ฌด์  ์‹œ๊ฐ„

ํ”Œ๋ ˆ์ด์–ด์—๊ฒŒ ํ•œ์ •๋œ ๊ตฌํ˜„ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

ํ”ผ๊ฒฉ ์‹œ ๋งŒ์•ฝ Hp๊ฐ€ 1 ์ด์ƒ์ด๋ผ๋ฉด 2์ดˆ๊ฐ„ ๋ฌด์ ์ด ๋˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

Timer์™€ isHit Boolean๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 2์ดˆ ๋’ค Bool๊ฐ’์„ ๋ณ€๊ฒฝํ•ด์ฃผ์–ด TakeDamage()๊ฐ€ ํ˜ธ์ถœ๋˜๋”๋ผ๋„ ๋กœ์ง์ด ์‹คํ–‰๋˜์ง€ ์•Š๋„๋ก ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

FTimerHandle isHitTime;
GetWorldTimerManager().SetTimer(isHitTime, this, &AMyPlayer::setCanHit,2.0f,false);

๋งˆ๋ฌด๋ฆฌ

์—ฌ๊ธฐ๊นŒ์ง€ Overlap Event๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ApplyDamage()์™€ TakeDamage()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”ผ๊ฒฉ ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•œ ๋‚ด์šฉ์ด์˜€์Šต๋‹ˆ๋‹ค.

profile
๊ฒŒ์ž„ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์–ด๋ณด์ž

0๊ฐœ์˜ ๋Œ“๊ธ€