Showing

[Unreal] 이중 포문을 활용한 총알 패턴 적용 본문

Unreal

[Unreal] 이중 포문을 활용한 총알 패턴 적용

RabbitCode 2023. 10. 27. 16:16

총알의 패턴을 다양하게 변경하기 위해 이중 for문을 활용할 수 있다.

6개의 총알이 나가는데, 홀짝에 따라 크기가 다르게 작성해보도록 한다.

// Fill out your copyright notice in the Description page of Project Settings.


#include "PlayerPawn.h"
#include "Components/BoxComponent.h"
#include "Components/ArrowComponent.h"
#include "Components/StaticMeshComponent.h"
//#include "EnhancedInputSubsystems.h"
//#include "EnhancedInputComponent.h"
#include "Bullet.h"
#include "Kismet/GameplayStatics.h"
#include "Kismet/KismetMathLibrary.h"

APlayerPawn::APlayerPawn()
{
	PrimaryActorTick.bCanEverTick = true;

	boxComp = CreateDefaultSubobject<UBoxComponent>(TEXT("My Box Component"));
	SetRootComponent(boxComp);
	boxComp->SetCollisionProfileName(TEXT("Player"));
	
	meshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("My Static Mesh"));
	meshComp->SetupAttachment(boxComp);

	FVector boxSize = FVector(50.0f, 50.0f, 50.0f);
	boxComp->SetBoxExtent(boxSize);

	firePosition = CreateDefaultSubobject<UArrowComponent>(TEXT("FirePos"));
	firePosition->SetupAttachment(meshComp);
	
	// 총알 발사 변수 초기화
	fireTimerTime = 0;  
	fireCoolTime = 2.0f; 
	fireReady = true;    // 발사 준비 On
	fireMode = 1;
}

void APlayerPawn::BeginPlay()
{
	Super::BeginPlay();
}

void APlayerPawn::FireCoolTimer(float cooltime, float deltaTime)
{
	if (fireTimerTime < cooltime) {
		fireTimerTime += deltaTime;
	}
	else 
	{
		fireTimerTime = 0;
		fireReady = true;
	}
}

void APlayerPawn::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	FVector dir = FVector(v,h,0);
	dir.Normalize();
	FVector newLocation = GetActorLocation() + dir * moveSpeed * DeltaTime;
	SetActorLocation(newLocation, true);
	
	if (fireReady == false) {
		FireCoolTimer(fireCoolTime, DeltaTime);
	}

	FHitResult _hitResult;
	UGameplayStatics::GetPlayerController(GetWorld(), 0)->GetHitResultUnderCursor(ECC_Visibility, true, _hitResult);
	FVector Dest = FVector(_hitResult.Location.X, _hitResult.Location.Y, 0.0f);
	FVector Start = FVector(this->GetActorLocation().X, this->GetActorLocation().Y, 0.0f);
	FRotator _dirRot = UKismetMathLibrary::FindLookAtRotation(Start,
		Dest);
	SetActorRotation(_dirRot);
}

void APlayerPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	PlayerInputComponent->BindAxis("Horizontal",this, &APlayerPawn::MoveHorizontal);
	PlayerInputComponent->BindAxis("Vertical", this, &APlayerPawn::MoveVertical);
	PlayerInputComponent->BindAction("Fire", IE_Pressed,this, &APlayerPawn::Fire);
}

void APlayerPawn::MoveHorizontal(float value) {h = value;}

void APlayerPawn::MoveVertical(float value) {v = value;}

void APlayerPawn::Fire()
{
	if (fireMode == 0) {
		// coolTime
		if (fireReady == true) {
			ABullet* bullet = GetWorld()->SpawnActor<ABullet>(bulletFactory, firePosition->GetComponentLocation()
				, firePosition->GetComponentRotation());
			fireReady = false;
			//fireSound
			//월드(어느 월드), 소리낼 사운드, 소리 날 위치
			UGameplayStatics::PlaySoundAtLocation(GetWorld(), fireSound, firePosition->GetComponentLocation());
		}
	}
	else if (fireMode == 1) {
		int bulletIndex = 1;
		if (fireReady == true) {
			for (int i = 0; i < 2; i++) {
				for (int j = 0; j < 3; j++) {
					// pos variable setting
					float zCod = -150.0f;
					float yCod = 150.0f;
					FVector posTemp = FVector(i * zCod, j * yCod, 0.0f);
					FVector targetPos = firePosition->GetComponentLocation() + posTemp;

					// produce bullet
					ABullet* bullet = GetWorld()->SpawnActor<ABullet>(bulletFactory, targetPos,firePosition->GetComponentRotation());
					bullet->SetActorScale3D(FVector(1, 1, 1));
					if (bulletIndex % 2 ==0) {
						bullet->SetActorScale3D(FVector(2, 2, 2)*2);
					}
					UGameplayStatics::PlaySoundAtLocation(GetWorld(), fireSound, targetPos);

					// bulletIndex counting
					bulletIndex += 1;
				}
			}
			// release fireReady
			fireReady = false;
		}
	}
}

 

 

(1) 총알들의 위치 선정

targetPos가 for문을 따라 변경될 수 있도록 적절하게 변경해준다. 

for (int i = 0; i < 2; i++) {
	for (int j = 0; j < 3; j++) {
		// pos variable setting
		float zCod = -150.0f;
		float yCod = 150.0f;
		FVector posTemp = FVector(i * zCod, j * yCod, 0.0f);
		FVector targetPos = firePosition->GetComponentLocation() + posTemp;

		// produce bullet
		ABullet* bullet = GetWorld()->SpawnActor<ABullet>(bulletFactory, targetPos,firePosition->GetComponentRotation());
		UGameplayStatics::PlaySoundAtLocation(GetWorld(), fireSound, targetPos);
	}
}

 

(2) bulletIndex에 따라 크기 변경

이중 포문 제일 내부에서 인덱싱처리를 해주면서 나머지 연산에 따라 홀짝마다 크기가 달라질 수 있도록 세팅해준다.

ABullet* bullet = GetWorld()->SpawnActor<ABullet>(bulletFactory, targetPos,firePosition->GetComponentRotation());
bullet->SetActorScale3D(FVector(1, 1, 1));
if (bulletIndex % 2 ==0) {
	bullet->SetActorScale3D(FVector(2, 2, 2)*2);
}
UGameplayStatics::PlaySoundAtLocation(GetWorld(), fireSound, targetPos);
// bulletIndex counting
bulletIndex += 1;