Like the subject implies, im having an issue with my chaos fractured blueprint object. The geometry collection the blueprint uses when dragged into the viewport and simulated works exactly as intended, the object seems to follow proper damage threshold setup, but my blueprint and c++ class object that I have created that uses this data seems to just instantly collapse no matter where I set any damage threshold for it. I was wondering if anyone knows why this might be happening, if this is an engine bug, or if there is some magic work around I havent found for this yet, but I need to be able to control this process from a blueprint… Its not very useful from a pragmatic standpoint otherwise.
// Fill out your copyright notice in the Description page of Project Settings.
#include "Building.h"
#include "GeometryCollection/GeometryCollectionComponent.h"
#include "Components/StaticMeshComponent.h"
// Sets default values
ABuilding::ABuilding() {
Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
RootComponent = Mesh;
GeoCollectionComponent = CreateDefaultSubobject<UGeometryCollectionComponent>(TEXT("GeoCollectionComponent"));
GeoCollectionComponent->SetupAttachment(RootComponent);
GeoCollectionComponent->SetNotifyBreaks(true);
bReplicates = true;
//this->SetReplicates(true);
//this->SetReplicateMovement(true);
}
// Called when the game starts or when spawned
void ABuilding::BeginPlay() {
Super::BeginPlay();
if (GeoCollectionComponent) {
// Bind to the break event for fragment detection
UE_LOG(LogTemp, Warning, TEXT("Binding to break event"));
//GeoCollectionComponent->OnChaosBreakEvent.AddDynamic(this, &ABuilding::OnGeometryBroken);
}
}
void ABuilding::OnGeometryBroken(const FChaosBreakEvent& BreakEvent) {
UE_LOG(LogTemp, Warning, TEXT("BreakEvent detected"));
if (!GeoCollectionComponent || !GeoCollectionComponent->RestCollection) return;
UE_LOG(LogTemp, Warning, TEXT("Fragment detected"));
const TSharedPtr<FGeometryCollection, ESPMode::ThreadSafe> Collection = GeoCollectionComponent->RestCollection->GetGeometryCollection();
if (!Collection.IsValid()) return;
int32 NumFragments = Collection->NumElements(FGeometryCollection::TransformGroup);
for (int32 i = 0; i < NumFragments; ++i) {
FTimerHandle TimerHandle;
FTimerDelegate TimerDelegate;
TimerDelegate.BindUFunction(this, FName("DisableFragment"), i);
GetWorld()->GetTimerManager().SetTimer(TimerHandle, TimerDelegate, FMath::RandRange(2.f, 5.f), false);
}
}
void ABuilding::DisableFragment(int32 Index) {
if (GeoCollectionComponent) {
// Hide the fragment visually and disable collision
GeoCollectionComponent->SetVisibility(false, true); // or per instance if needed
GeoCollectionComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
// If you want to destroy the entire actor when all fragments are gone, implement tracking
}
}
// Called every frames
/*
void ABuilding::Tick(float DeltaTime){
Super::Tick(DeltaTime);
}
*/
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Building.generated.h"
class UStaticMeshComponent;
class UGeometryCollectionComponent;
UCLASS()
class MONSTERWARS_API ABuilding : public AActor {
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ABuilding();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
//virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere, Category = "Effects")
UStaticMeshComponent* Mesh;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Chaos")
TObjectPtr<UGeometryCollectionComponent> GeoCollectionComponent;
// NOTE: You need to declare OnGeometryBroken and DisableFragment in the header:
UFUNCTION()
void OnGeometryBroken(const FChaosBreakEvent& BreakEvent);
UFUNCTION()
void DisableFragment(int32 Index);
};
On the left is my geometry collection dragged into the scene:
On the right is my blueprint which includes that geometry data: