添加 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