- Activate a Chaos Destruction VFX effect during a multiplayer game, causing the call of UNiagaraDataInterfaceChaosDestruction::InitPerInstanceData
- A new Solver is added from the SystemInstance to the Solvers Array of UNiagaraDataInterfaceChaosDestruction
- The host starts a ServerTravel with all the clients
We can notice that the dtor of the FEventManager is called through the FChaosSolversModule::DestroySolver method that is called through the GarbageCollector. The dtor of FEventManager calls ***FEventManager::Reset()*invalidating the EventContainers Array. This series of calls can be made before the call UNiagaraDataInterfaceChaosDestruction::BeginDestroy() that is also called trough the GarbageCollector.
When UNiagaraDataInterfaceChaosDestruction::BeginDestroy() calls FEventManager::UnregisterHandler() the game crashes on ContainerLock.ReadLock(); or in checkf(EventID < EventContainers.Num(), TEXT(“Unregistering event Handler for an event ID that does not exist”));
Curiously, this seems to happen only during the server travel. If the UNiagaraDataInterfaceChaosDestruction::BeginDestroy() is called after the server travel is finished, the SolverData.Solver->GetEventManager() seems to be nullptr.
`void UNiagaraDataInterfaceChaosDestruction::BeginDestroy()
{
Super::BeginDestroy();
for (FSolverData& SolverData : Solvers)
{
Chaos::FEventManager* EventManager = SolverData.Solver->GetEventManager();
if (EventManager)
{
EventManager->UnregisterHandler(Chaos::EEventType::Collision, this);
EventManager->UnregisterHandler(Chaos::EEventType::Breaking, this);
EventManager->UnregisterHandler(Chaos::EEventType::Trailing, this);
}
}
Solvers.Reset();
}
void FEventManager::UnregisterHandler(const EEventType& EventType, const void* InHandler)
{
const FEventID EventID = (FEventID)EventType;
ContainerLock.ReadLock();
checkf(EventID < EventContainers.Num(), TEXT(“Unregistering event Handler for an event ID that does not exist”));
EventContainers[EventID]->UnregisterHandler(InHandler);
ContainerLock.ReadUnlock();
}`