添加 Source/FLESH/Private/Gore/BloodPool.cpp
This commit is contained in:
155
Source/FLESH/Private/Gore/BloodPool.cpp
Normal file
155
Source/FLESH/Private/Gore/BloodPool.cpp
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
// @ 2025, Copyright Virtuos Games. All rights reserved.
|
||||||
|
|
||||||
|
#include "Gore/BloodPool.h"
|
||||||
|
|
||||||
|
#include "Components/BoxComponent.h"
|
||||||
|
#include "Components/DecalComponent.h"
|
||||||
|
#include "UObject/ConstructorHelpers.h"
|
||||||
|
#include "Materials/MaterialInterface.h"
|
||||||
|
#include "NiagaraComponent.h"
|
||||||
|
#include "NiagaraFunctionLibrary.h"
|
||||||
|
|
||||||
|
// Sets default values
|
||||||
|
ABloodPool::ABloodPool()
|
||||||
|
{
|
||||||
|
PrimaryActorTick.bCanEverTick = true;
|
||||||
|
PrimaryActorTick.bStartWithTickEnabled = false;
|
||||||
|
|
||||||
|
// Create root component
|
||||||
|
USceneComponent* Root = CreateDefaultSubobject<USceneComponent>("Root");
|
||||||
|
SetRootComponent(Root);
|
||||||
|
|
||||||
|
// Create decal component
|
||||||
|
Decal = CreateDefaultSubobject<UDecalComponent>("Decal");
|
||||||
|
Decal->SetupAttachment(Root);
|
||||||
|
Decal->DecalSize = FVector(100);
|
||||||
|
Decal->SetRelativeRotation(FRotator(-90,0,0));
|
||||||
|
Decal->SetFadeIn(-0.2f, 0.3f);
|
||||||
|
|
||||||
|
// Try to load default decal material if not set
|
||||||
|
if(!DecalMaterial)
|
||||||
|
{
|
||||||
|
static ConstructorHelpers::FObjectFinder<UMaterialInterface> DefaultDecalMaterial(TEXT("/Game/FLESH/Gore/Textures/M_Decal_BloodPool"));
|
||||||
|
if(DefaultDecalMaterial.Succeeded())
|
||||||
|
{
|
||||||
|
DecalMaterial = DefaultDecalMaterial.Object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to load default Niagara system if not set
|
||||||
|
static ConstructorHelpers::FObjectFinder<UNiagaraSystem> DefaultNiagaraSystem(TEXT("/Game/FLESH/Gore/Niagara/NS_DIS_BloodBurst"));
|
||||||
|
if(DefaultNiagaraSystem.Succeeded())
|
||||||
|
{
|
||||||
|
BloodBurstSystem = DefaultNiagaraSystem.Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Niagara component for blood burst effect
|
||||||
|
BloodBurstEffect = CreateDefaultSubobject<UNiagaraComponent>("BloodBurstEffect");
|
||||||
|
BloodBurstEffect->SetupAttachment(Root);
|
||||||
|
BloodBurstEffect->bAutoActivate = false;
|
||||||
|
|
||||||
|
// Create collision component
|
||||||
|
Collision = CreateDefaultSubobject<UBoxComponent>("Collision");
|
||||||
|
Collision->SetupAttachment(Root);
|
||||||
|
Collision->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
|
||||||
|
Collision->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
|
||||||
|
Collision->InitBoxExtent(FVector(100));
|
||||||
|
|
||||||
|
// Set up collision response for specific channel
|
||||||
|
Collision->SetCollisionResponseToChannel(ECC_GameTraceChannel4, ECR_Overlap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABloodPool::BeginPlay()
|
||||||
|
{
|
||||||
|
Super::BeginPlay();
|
||||||
|
|
||||||
|
// Load default decal material if not set
|
||||||
|
if(!DecalMaterial)
|
||||||
|
{
|
||||||
|
DecalMaterial = LoadObject<UMaterialInterface>(nullptr, TEXT("/Game/FLESH/Gore/Textures/M_Decal_BloodPool"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load default Niagara system if not set
|
||||||
|
if(!BloodBurstSystem)
|
||||||
|
{
|
||||||
|
BloodBurstSystem = LoadObject<UNiagaraSystem>(nullptr, TEXT("/Game/FLESH/Gore/Niagara/NS_DIS_BloodBurst"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up decal properties
|
||||||
|
Decal->SetFadeIn(StartDelay, InterpTime);
|
||||||
|
Decal->SetRelativeScale3D(RemapSizeForDecal(DecalSize));
|
||||||
|
Decal->SetDecalMaterial(DecalMaterial);
|
||||||
|
Decal->SetRelativeRotation(DecalRotation);
|
||||||
|
Decal->AddRelativeRotation(FRotator(-90, FMath::FRandRange(-10.f, 10.f), 0));
|
||||||
|
Decal->SetFadeOut(MaxLifetime / 5, MaxLifetime, false);
|
||||||
|
|
||||||
|
// Set up collision properties
|
||||||
|
Collision->SetRelativeRotation(DecalRotation);
|
||||||
|
Collision->SetRelativeScale3D(DecalSize);
|
||||||
|
|
||||||
|
// Activate blood burst effect
|
||||||
|
if(BloodBurstSystem && BloodBurstEffect)
|
||||||
|
{
|
||||||
|
BloodBurstEffect->SetAsset(BloodBurstSystem);
|
||||||
|
BloodBurstEffect->Activate(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FVector ABloodPool::RemapSizeForDecal(const FVector In) const
|
||||||
|
{
|
||||||
|
FVector Out;
|
||||||
|
Out.X = In.Z;
|
||||||
|
Out.Y = In.Y;
|
||||||
|
Out.Z = In.X;
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ABloodPool* ABloodPool::CreateBloodPool(UWorld* World, const FVector& Location, float Scale, TSubclassOf<ABloodPool> BloodPoolTemplate)
|
||||||
|
{
|
||||||
|
if (!World)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use default blood pool template (if not provided)
|
||||||
|
TSubclassOf<ABloodPool> PoolTemplate = BloodPoolTemplate;
|
||||||
|
if (!PoolTemplate)
|
||||||
|
{
|
||||||
|
// Use ABloodPool class as default
|
||||||
|
PoolTemplate = ABloodPool::StaticClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PoolTemplate)
|
||||||
|
{
|
||||||
|
// Trace downward to find the ground
|
||||||
|
FHitResult HitResult;
|
||||||
|
FCollisionQueryParams QueryParams;
|
||||||
|
QueryParams.bTraceComplex = false;
|
||||||
|
|
||||||
|
if (World->LineTraceSingleByChannel(
|
||||||
|
HitResult,
|
||||||
|
Location,
|
||||||
|
Location - FVector(0, 0, 500),
|
||||||
|
ECC_Visibility,
|
||||||
|
QueryParams
|
||||||
|
))
|
||||||
|
{
|
||||||
|
FVector PoolLocation = HitResult.Location + FVector(0, 0, 1); // Slightly above the ground
|
||||||
|
|
||||||
|
// Spawn blood pool
|
||||||
|
FActorSpawnParameters SpawnParams;
|
||||||
|
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||||
|
ABloodPool* BloodPool = World->SpawnActor<ABloodPool>(PoolTemplate, PoolLocation, FRotator::ZeroRotator, SpawnParams);
|
||||||
|
|
||||||
|
// Apply scale
|
||||||
|
if (BloodPool)
|
||||||
|
{
|
||||||
|
BloodPool->SetActorScale3D(FVector(Scale));
|
||||||
|
return BloodPool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
Reference in New Issue
Block a user