Changing Rest Collection of Chaos Geometry Collection Component at runtime

I am facing a problem that shouldn’t be this complicated.
I have an item that I want to break so I generated a geometry collection form it’s static mesh and added it to the blueprint and handle switching between the static mesh and geometry collection at component hit event and all works fine, now I have many items that all inherit from a parent and at begin i get a data table to set the item’s static mesh and different other properties and the problem I am facing is changing the rest collection in the geometry collection component at runtime, I can’t figure it out for the life of me.
is it even doable in blueprints?
when i drag off of Geometry Collection Component i can only find “get Rest Collection” i can’t set it, and dragging off of Rest Collection i can only find Geometry Source Array, i tried setting, clearing and adding to the Geometry Source Array but it gives me access none error because Geometry Source array is flagged as Editor-Only.
i also tried setting Chaos Geometry Collection Component itself to something else from a variable but when i play it stays as it’s default value and not the new variable.
i tried on the event graph and construction script with no results.

Any help or screenshots would be much appreciated.

Thank you.



2 Likes

GeometryCollectionComponent has a SetRestCollection function but does not expose it to blueprints.
Unfortunately, I think it needs to be handled in C++.

If you are using the source code version of UE, you only need to add a UFUNCTION macro to the SetRestCollection function in GeometryCollectionComponent.h.

If you are using the binary version, you will need to add a C++
class and create a function that assigns an asset reference to the RestCollection variable.

2 Likes

It seems this has changed. The function is available but does not change the RestCollection when called in Blueprints. Maybe this is a bug but its not easy to tell if some other condition(s) need to be met before calling SetRestCollection

Thank you, I followed your advice and got it to work!

GeometryCollectionComponent.h

/** Sets a new Rest Collection. */
UFUNCTION(BlueprintCallable, Category = "ChaosPhysics")
void UpdateRestCollection(const UGeometryCollection* RestCollectionIn);

GeometryCollectionComponent.cpp

void UGeometryCollectionComponent::UpdateRestCollection(const UGeometryCollection* RestCollectionIn)
{
	SetRestCollection(RestCollectionIn);
}
1 Like

Were you able to get it to work in Blueprint or only in c++?
I’m having an issue where I call to set the rest collection in BP my print string returns the correct asset name but I’m getting absolutely nothing when it should be adding the geometry collection and I’m a little confused is this “Set rest collection” just a bugged node


?

I have same problem ‘Set Rest Collection’ does nothing

1 Like

Any luck with this?

interactive geometry

Set Rest Collection is actually crashing the editor for me when called in the construction script of my BP. Trying to switch out the Collection based on an enum and it crashes.
Here is the error:

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION 0x000000000066e633

UnrealEditor_Chaos!FGeometryCollectionPhysicsProxy::PullFromPhysicsState() [D:\build\++UE5\Sync\Engine\Source\Runtime\Experimental\Chaos\Private\PhysicsProxy\GeometryCollectionPhysicsProxy.cpp:3511]
UnrealEditor_Engine!Chaos::FPhysicsSolverBase::PullPhysicsStateForEachDirtyProxy_External<`FPhysScene_Chaos::OnSyncBodies'::`2'::FDispatcher>() [D:\build\++UE5\Sync\Engine\Source\Runtime\Experimental\Chaos\Public\Chaos\PhysicsSolverBaseImpl.h:160]
UnrealEditor_Engine!FPhysScene_Chaos::OnSyncBodies() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\PhysicsEngine\Experimental\PhysScene_Chaos.cpp:2265]
UnrealEditor_PhysicsCore!FChaosScene::SyncBodies<Chaos::FPBDRigidsSolver>() [D:\build\++UE5\Sync\Engine\Source\Runtime\PhysicsCore\Private\ChaosScene.cpp:440]
UnrealEditor_PhysicsCore!`FChaosScene::EndFrame'::`65'::<lambda_1>::operator()<Chaos::FPBDRigidsSolver>() [D:\build\++UE5\Sync\Engine\Source\Runtime\PhysicsCore\Private\ChaosScene.cpp:540]
UnrealEditor_PhysicsCore!FChaosScene::EndFrame() [D:\build\++UE5\Sync\Engine\Source\Runtime\PhysicsCore\Private\ChaosScene.cpp:535]
UnrealEditor_Engine!TBaseUObjectMethodDelegateInstance<0,UWorld,void __cdecl(void),FDefaultDelegateUserPolicy>::ExecuteIfSafe() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Delegates\DelegateInstancesImpl.h:667]
UnrealEditor_Engine!FSimpleDelegateGraphTask::DoTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:1601]
UnrealEditor_Engine!TGraphTask<FSimpleDelegateGraphTask>::ExecuteTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:1265]
UnrealEditor_Core!FNamedTaskThread::ProcessTasksNamedThread() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:758]
UnrealEditor_Core!FNamedTaskThread::ProcessTasksUntilQuit() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:649]
UnrealEditor_Core!FTaskGraphCompatibilityImplementation::WaitUntilTasksComplete() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:2125]
UnrealEditor_Engine!FTickTaskSequencer::ReleaseTickGroup() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:556]
UnrealEditor_Engine!FTickTaskManager::RunTickGroup() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\TickTaskManager.cpp:1583]
UnrealEditor_Engine!UWorld::RunTickGroup() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\LevelTick.cpp:771]
UnrealEditor_Engine!UWorld::Tick() [D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\LevelTick.cpp:1537]
UnrealEditor_UnrealEd!UEditorEngine::Tick() [D:\build\++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\EditorEngine.cpp:1924]
UnrealEditor_UnrealEd!UUnrealEdEngine::Tick() [D:\build\++UE5\Sync\Engine\Source\Editor\UnrealEd\Private\UnrealEdEngine.cpp:531]
UnrealEditor!FEngineLoop::Tick() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:5825]
UnrealEditor!GuardedMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Launch.cpp:188]
UnrealEditor!GuardedMainWrapper() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:118]
UnrealEditor!LaunchWindowsStartup() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:258]
UnrealEditor!WinMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:298]
UnrealEditor!__scrt_common_main_seh() [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
kernel32
ntdll

I got exactly the same problem. Is there a solution? Would save me a lot of time.

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION 0x0000000000000000

UnrealEditor_Chaos
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_PhysicsCore
UnrealEditor_PhysicsCore
UnrealEditor_PhysicsCore
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Core
UnrealEditor_Core
UnrealEditor_Core
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_UnrealEd
UnrealEditor_UnrealEd
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
kernel32
ntdll

Found a solution that worked for me. I will note that I am not using SetRestCollection inside the ConstructionScript but I am using it when I have rounds restart in my game mode.

SetCollisionEnabled(ECollisionEnabled::NoCollision);

FGeometryCollectionPhysicsProxy* TempPhysicsProxy = GetPhysicsProxy();
if (TempPhysicsProxy)
{
	FPhysScene_Chaos* Scene = GetInnerChaosScene();
	Scene->RemoveObject(TempPhysicsProxy);
	InitializationState = ESimulationInitializationState::Unintialized;

	ResetRepData();
}

SetRestCollection(RestCollection);


// Enables simulated physics
const TWeakObjectPtr<UPrimitiveComponent> PreviousOwnerComponent = BodyInstance.OwnerComponent;
{
	BodyInstance.OwnerComponent = nullptr;
	BodyInstance.SetInstanceSimulatePhysics(true);
	BodyInstance.OwnerComponent = PreviousOwnerComponent;
}

RegisterAndInitializePhysicsProxy();

SetDynamicState(Chaos::EObjectStateType::Dynamic);

//
//Set Any Collision Responses here BEFORE calling SetCollisionEnabled()
//

SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);

SetNotifyBreaks(true);
OnActorEnableCollisionChanged();

// This is needed to assign our GeometryCollection events to work with our new PhysicsProxy 
RegisterForEvents();

From what I saw if you are going to switch the RestCollection (Which in turn changes the DynamicCollection) you have to reset the PhysicsProxy.

Quick Update:

It looks like UE 5.4 broke (or somewhat broke) how GeometryCollection Notifies work and unfortunately without having a manually compiled engine you cannot fix the issue. (yet)

SetNotifyBreaks(true) would immediately stop all break events from happening as soon as it got called. In 5.4 this is no longer the case. Calling SetNotifyBreaks(true) will allow on average 30 break events to get called until it is finally updated. The solution from what I have seen so far is to manually access the EventDispatcher and Unregister the event. However even if you parent GeometryCollectionComponent you do not have access to EventDispatcher since it is private.

I will give further updates as I look into finding a solution that would be doable with read-only engine code.