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

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

Project Galaga

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

๊ฐœ์š”

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

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

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

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

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

๐Ÿš€ Project Galaga Github Repository


๋ณธ๋ก 


ํ”Œ๋ ˆ์ด์–ด ๊ตฌํ˜„

MyPlayer Class

ํ”Œ๋ ˆ์ด์–ด๋Š” Pawn Class๋ฅผ ์ƒ์†ํ•˜์—ฌ ๊ฐœ๋ฐœํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์šฐ์ฃผ์„  ์—์…‹์˜ Static Mesh๋งŒ์„ ์ž…ํžˆ๊ณ , ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋”ฐ๋กœ ํ•„์š”์—†๋‹ค๊ณ  ์ƒ๊ฐํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

ํ”Œ๋ ˆ์ด์–ด ์™ธํ˜•

ํ”Œ๋ ˆ์ด์–ด์˜ ์™ธํ˜•์€ Collision๋ฅผ ๋ฃจํŠธ๋กœ, Static Mesh๋ฅผ ์ž์‹์œผ๋กœ ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

public: // Component
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = PlayerBody, meta = (AllowPrivateAccess = true))
	class UStaticMeshComponent* PlayerBody;

	UPROPERTY(VisibleAnywhere, Category = PlayerBody)
	class USphereComponent* PlayerBodyCollision;
// Sets default values
AMyPlayer::AMyPlayer()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	PlayerBodyCollision = CreateDefaultSubobject<USphereComponent>(TEXT("PlayerBodyCollision"));
	RootComponent = PlayerBodyCollision;

	PlayerBody = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("PlayerBody"));
	PlayerBody->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	PlayerBody->SetRelativeScale3D(FVector(0.02f, 0.02f, 0.02f));
	PlayerBody->SetupAttachment(PlayerBodyCollision);

	ConstructorHelpers::FObjectFinder<UStaticMesh>PlayerBodyMesh(TEXT("/Script/Engine.StaticMesh'/Game/spaceship-cb2/source/StaticMesh.StaticMesh'"));

	if (PlayerBodyMesh.Succeeded())
	{
		PlayerBody->SetStaticMesh(PlayerBodyMesh.Object);
	}

	PlayerBodyCollision->SetCollisionProfileName(TEXT("BlockAll"));

}

ํ”Œ๋ ˆ์ด์–ด ์กฐ์ž‘

ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์˜ ์›€์ง์ž„์€ Old Input System์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์›€์ง์ž„๊ณผ ๊ณต๊ฒฉ์œผ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ๊ฐ๊ฐ ์•กํ„ฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ์ž‘ํ•ด ์ถ”๊ฐ€ํ•˜์—ฌ ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

void AMyPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	
	PlayerMove->SetupInputBinding(PlayerInputComponent);
	PlayerAttack->SetupInputBinding(PlayerInputComponent);


	PlayerInputComponent->BindAction(TEXT("Boom"), IE_Pressed, this, &AMyPlayer::Boom);
	PlayerInputComponent->BindAction(TEXT("Pause"), IE_Pressed, this, &AMyPlayer::Pause);


}

์›€์ง์ž„

ํ”Œ๋ ˆ์ด์–ด์˜ ์›€์ง์ž„์€ W, A, S, D 4๊ฐ€์ง€์˜ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒํ•˜์ขŒ์šฐ๋กœ ์กฐ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

Axis๊ฐ’์— ๋”ฐ๋ผ Direction์œผ๋กœ ์ด๋™๋ฐฉํ–ฅ์„ ๊ฒฐ์ •ํ•œ ๋’ค, ๋“ฑ์†์šด๋™ ๊ณต์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”Œ๋ ˆ์ด์–ด์˜ ์ด๋™์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

P(๊ฒฐ๊ณผ ์œ„์น˜) = P0(ํ˜„์žฌ ์œ„์น˜) + v(์†๋„) * t(์‹œ๊ฐ„)

void UPlayerMove::Move(float DeltaTime)
{
	FVector P0 = me->GetActorLocation();
	FVector vt = DeltaTime * MoveSpeed * Direction;

	FVector P = P0 + vt;

	me->SetActorLocation(P, true);
	Direction = FVector::ZeroVector;
}

ํ”Œ๋ ˆ์ด์–ด ๊ณต๊ฒฉ

ํ”Œ๋ ˆ์ด์–ด์˜ ๊ณต๊ฒฉ์€ Action์œผ๋กœ ๊ฐ’์„ ๋ฐ›์•„ isAttack์„ ์ „ํ™˜ํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

void UPlayerAttack::SetupInputBinding(UInputComponent* PlayerInputComponent)
{
	PlayerInputComponent->BindAction(TEXT("Fire"), IE_Pressed, this, &UPlayerAttack::Fire);
	PlayerInputComponent->BindAction(TEXT("Fire"), IE_Released, this, &UPlayerAttack::Fire);
}

isAttack์ด ์ฐธ์ผ ๋•Œ๋งŒ AttackSpeedTimer์— Deltatime์„ ๋”ํ•˜์—ฌ ๊ณต๊ฒฉ์†๋„ ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ดˆ๊ธฐ์—๋Š” Player Bullet์„ ์ƒ์„ฑํ•ด์ฃผ์—ˆ์œผ๋‚˜ ์ถ”ํ›„ ์˜ค๋ธŒ์ ํŠธ ํ’€๋ง์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌํŒฉํ† ๋งํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋ธŒ์ ํŠธ ํ’€๋ง์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ ์ดํ›„ ํฌ์ŠคํŒ…์—์„œ ์ž์„ธํžˆ ์ ๊ฒ ์Šต๋‹ˆ๋‹ค.

void UPlayerAttack::FireBullet(float DeltaTime)
{

	AttackSpeedTimer += DeltaTime;

	if (AttackSpeedTimer >= AttackSpeed)
	{
		me->FireSound();
		//FActorSpawnParameters param;
		//param.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
		//APlayerBullet* bullet = GetWorld()->SpawnActor<APlayerBullet>(BulletFactory, GetActorLocation(), FRotator::ZeroRotator, param);

		me->PlayerBulletPool->SpawnPlayerPooledBullet();

		AttackSpeedTimer = 0.0f;
	}
}

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ๊ฐ„๋‹จํ•œ ์กฐ์ž‘๊ตฌํ˜„์ž…๋‹ˆ๋‹ค.

ํญํƒ„, ํ•„์‚ด๊ธฐ๋Š” ๋‹ค๋ฅธ ์š”์†Œ์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ๋”ฐ๋กœ ํฌ์ŠคํŒ…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


๋งˆ๋ฌด๋ฆฌ

์—ฌ๊ธฐ๊นŒ์ง€ ํ”Œ๋ ˆ์ด์–ด ์กฐ์ž‘์— ๋Œ€ํ•œ ๊ตฌํ˜„๋‚ด์šฉ์ด์˜€์Šต๋‹ˆ๋‹ค.

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

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