언리얼 엔진/Mini Projects [Unreal]
[FPSScoring] 총알
라구넹
2025. 2. 27. 07:34
// h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "FSBullet.generated.h"
UCLASS()
class FPSSCORING_API AFSBullet : public AActor
{
GENERATED_BODY()
public:
AFSBullet();
protected:
UFUNCTION()
void OnComponentBeginOverlapCallback(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepHitResult);
UPROPERTY()
TObjectPtr<class USphereComponent> Trigger;
UPROPERTY()
TObjectPtr<class UStaticMeshComponent> StaticMeshComp;
UPROPERTY()
TObjectPtr<class UProjectileMovementComponent> Movement;
};
// cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Actor/FSBullet.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "Components/SphereComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Physics/FSCollision.h"
#include "Subsystem/FSScoreSubsystem.h"
#include "Game/FSGameMode.h"
// Sets default values
AFSBullet::AFSBullet()
{
Trigger = CreateDefaultSubobject<USphereComponent>(TEXT("Trigger"));
Trigger->InitSphereRadius(5.0f);
Trigger->SetCollisionProfileName(CPROFILE_FSTRIGGER);
RootComponent = Trigger;
Trigger->OnComponentBeginOverlap.AddDynamic(this, &AFSBullet::OnComponentBeginOverlapCallback);
StaticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMeshComp"));
static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMeshRef(TEXT("/Script/Engine.StaticMesh'/Game/Mesh/SM_Bullet.SM_Bullet'"));
if (StaticMeshRef.Succeeded())
{
StaticMeshComp->SetStaticMesh(StaticMeshRef.Object);
}
StaticMeshComp->SetRelativeScale3D(FVector(0.1f, 0.1, 0.1f));
StaticMeshComp->SetupAttachment(RootComponent);
StaticMeshComp->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
Movement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("Movement"));
Movement->InitialSpeed = 3000.0f;
Movement->MaxSpeed = 3000.0f;
Movement->bRotationFollowsVelocity = true;
Movement->bShouldBounce = false;
InitialLifeSpan = 3.0f;
}
void AFSBullet::OnComponentBeginOverlapCallback(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepHitResult)
{
UFSScoreSubsystem* ScoreSubsystem = GetWorld()->GetSubsystem<UFSScoreSubsystem>();
if (ScoreSubsystem)
{
ScoreSubsystem->SetScore(ScoreSubsystem->GetScore() + 1);
UE_LOG(LogTemp, Log, TEXT("Hit! - %d"), ScoreSubsystem->GetScore());
AFSGameMode* GameMode = Cast<AFSGameMode>(GetWorld()->GetAuthGameMode());
GameMode->SetScoreText(FString::FromInt(ScoreSubsystem->GetScore()));
}
OtherActor->Destroy();
Destroy();
}
액터에 UProjectileMovementComponent 달아서 사용
void AFSCharacterPlayer::Shoot()
{
if (bIsShooted) return;
bIsShooted = true;
FVector SpawnLocation = GetActorLocation() + GetActorForwardVector() * 100.0f;
FRotator SpawnRotation = GetControlRotation();
FActorSpawnParameters SpawnParams;
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
AFSBullet* Bullet = GetWorld()->SpawnActor<AFSBullet>(AFSBullet::StaticClass(), SpawnLocation, SpawnRotation, SpawnParams);
}
플레이어가 쏠 때 회전 ControlRotation으로 정해주면 됨