언리얼4 멀티 플레이 폭격 구현

Intro

  • 멀티 플레이 폭격 구현

폭격기 액터

AJet::AJet()
{
 	// 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;

	CanBombing = false;

	JetStatic = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("JetStaticMesh"));
	JetStatic->SetupAttachment(RootComponent);

	JetAudio = CreateDefaultSubobject<UAudioComponent>(TEXT("JetAudio"));
	JetAudio->SetupAttachment(JetStatic);

	BombSphere = CreateDefaultSubobject<USphereComponent>(TEXT("BombSphere"));
	BombSphere->SetupAttachment(JetStatic);

	GetCharacterMovement()->DefaultLandMovementMode = MOVE_Flying;
	GetCharacterMovement()->MaxFlySpeed = 1000000.0;
	
}

// Called when the game starts or when spawned
void AJet::BeginPlay()
{
	Super::BeginPlay();


	FTimerDelegate StopBombing;
	FTimerHandle StopTimer;
	
	FTimerDelegate StartBombing;
	FTimerHandle StartTimer;


	StopBombing.BindLambda([this]()
	{
		CanBombing = false;
	
	});


	StartBombing.BindLambda([this]()
	{
		CanBombing = true;
		BombingServer();
	
	});


	GetWorld()->GetTimerManager().SetTimer(StartTimer, StartBombing, 2.5f, false);
	GetWorld()->GetTimerManager().SetTimer(StopTimer, StopBombing, 5.0f, false);
}


void AJet::BombingServer_Implementation()
{
	FTimerHandle Timer;
	if (CanBombing)
	{
		BombingMulticast();
		GetWorld()->GetTimerManager().SetTimer(Timer, this, &AJet::BombingServer , 0.3f, false); // 0.3 초 마다 폭탄 스폰
	}
}

bool AJet::BombingServer_Validate()
{
	return true;
	
}

void AJet::BombingMulticast_Implementation()
{
	FTransform BombTransform = BombSphere->GetComponentTransform();
	
	//UKismetMathLibrary::Conv_VectorToTransform();
	
	GetWorld()->SpawnActor<ABomb>(BombClass, BombTransform);
}

// Called every frame
void AJet::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	//FRotator JetRotation = GetActorRotation();
	FVector JetForwardVector = GetActorForwardVector();
	
	GetCharacterMovement()->AddInputVector(JetForwardVector);
}

void AJet::Destroyed()
{
	Super::Destroyed();

	GetWorld()->GetTimerManager().ClearAllTimersForObject(this); // 소멸시 타이머 초기화
}

Tick에서 AddInputVector를 통해 앞으로 이동하게끔 했으며 Beginplay에서 Timer를 통해 2.5초뒤 폭격이 시작되며 0.3초마다 폭탄 액터를 서버에 스폰한다.

5초가되면 CanBombingfalse로 세팅해 폭탄 스폰을 중지한다.

폭탄 액터

ABomb::ABomb()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	RootComp = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
	RootComponent = RootComp;

	BombMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BombMesh"));
	BombMesh->SetupAttachment(RootComponent);

	BombSphere = CreateDefaultSubobject<USphereComponent>(TEXT("BombSphere"));
	BombSphere->SetupAttachment(BombMesh);

	BombParticle = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("BombParticle"));
	BombParticle->SetupAttachment(BombMesh);

	static ConstructorHelpers::FObjectFinder<USoundCue>EXPLO(TEXT("SoundCue'/Game/Sound/Explosioncue.Explosioncue'"));
	if (EXPLO.Succeeded())
	{
		ExplosionCue = EXPLO.Object;
	}
}

// Called when the game starts or when spawned
void ABomb::BeginPlay()
{
	Super::BeginPlay();
	
	BombSphere->OnComponentBeginOverlap.AddDynamic(this, &ABomb::BombOverlap);
}

void ABomb::BombOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	FVector BombLocation = BombSphere->GetComponentLocation();
	UGameplayStatics::PlaySoundAtLocation(this, ExplosionCue, BombLocation);

	BombParticle->Activate();

	UGameplayStatics::ApplyRadialDamage(GetWorld(), 3000.0f, BombLocation, 1000.0f, nullptr, TArray<AActor*>(), this, false);
}

Sphere콜리전이 지면과 Overlap시 폭발 파티클과 RadialDamage를 주는 액터 구성

실행 결과

1

참고 자료

댓글남기기