Hello Everyone,
I am making a 2.5D game and for performance reasons, I decided to divide my Map into regions.
im enabling / disabling entities located in regions too far to be considered by Frustum Culling and Physics.
but after disabling / enabling some entities loses their FrozenRendererSceneTag and makes the Hybrid Renderer slower.
note: my full scene is static and all entities within the subscene are tagged by the FrozenRendererSceneTag before this system runs.
[UpdateInGroup(typeof(SimulationSystemGroup))]
public class RegionChangedEventConsumerSystem : SystemBase
{
EndSimulationEntityCommandBufferSystem endSimulationEntityCommandBufferSystem;
EntityQuery m_RegionsQuery;
EntityQuery m_RegionChangedEventQuery;
protected override void OnCreate()
{
endSimulationEntityCommandBufferSystem = World.GetExistingSystem<EndSimulationEntityCommandBufferSystem>();
var queryDescription = new EntityQueryDesc
{
All = new ComponentType[] { ComponentType.ReadOnly<WorldMapRegion>()},
Options = EntityQueryOptions.IncludeDisabled
};
m_RegionsQuery = GetEntityQuery(queryDescription);
m_RegionChangedEventQuery = GetEntityQuery(ComponentType.ReadOnly<RegionChangedEvent>());
//without this call the system will still run even without RegionChangedEvent Component
this.RequireForUpdate(m_RegionChangedEventQuery);
}
protected override void OnUpdate()
{
// var commandBuffer = EntityManager;
var commandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer();
Entities
.WithoutBurst()
.WithStructuralChanges()
.ForEach((Entity entity, in RegionChangedEvent regionChangedEvent) =>
{
/* var commandBuffer2 = beginPresentationEntityCommandBufferSystem.CreateCommandBuffer();
commandBuffer2.DestroyEntity(entity);
*/
commandBuffer.DestroyEntity(entity);
var currentActiveRegions = GeoUtils.GetConcernedRegionsAsNativeArray(regionChangedEvent.CurrentRegion, Allocator.Temp);
//Teleport or initialization
if (math.abs(regionChangedEvent.CurrentRegion.x - regionChangedEvent.OldRegion.x) > 1 || (math.abs(regionChangedEvent.CurrentRegion.y - regionChangedEvent.OldRegion.y) > 1))
{
EntityManager.AddComponent<Disabled>(m_RegionsQuery);
//Activate all Included region
for (var i=0; i< currentActiveRegions.Length ; i++)
{
m_RegionsQuery.SetSharedComponentFilter(new WorldMapRegion { value = currentActiveRegions[i] });
commandBuffer.RemoveComponent<Disabled>(m_RegionsQuery);
m_RegionsQuery.ResetFilter();
}
currentActiveRegions.Dispose();
return;
}
//Normal region culling behavior
//Regions to Enable
var concernedRegions = new NativeList<int2>(9, Allocator.Temp);
for (var i = 0; i < currentActiveRegions.Length; i++)
//add excluded Regions from Old Player Region (New Regions)
if (math.abs(regionChangedEvent.OldRegion.x - currentActiveRegions[i].x) > 1 || (math.abs(regionChangedEvent.OldRegion.y - currentActiveRegions[i].y) > 1))
concernedRegions.Add(currentActiveRegions[i]);
var regionsCount = concernedRegions.Length;
//Enable all Included regions
for (var i = 0; i < regionsCount; i ++)
{
var worldMapRegion = new WorldMapRegion { value = concernedRegions[i] };
m_RegionsQuery.SetSharedComponentFilter(worldMapRegion);
commandBuffer.RemoveComponent<Disabled>(m_RegionsQuery);
m_RegionsQuery.ResetFilter();
}
currentActiveRegions.Dispose();
//Regions to Disable
concernedRegions.Clear();
var oldActiveRegions = GeoUtils.GetConcernedRegionsAsNativeArray(regionChangedEvent.OldRegion, Allocator.Temp);
for (var i = 0; i < oldActiveRegions.Length; i++)
//add excluded Regions from Old Player Region (New Regions)
if (math.abs(regionChangedEvent.CurrentRegion.x - oldActiveRegions[i].x) > 1 || (math.abs(regionChangedEvent.CurrentRegion.y - oldActiveRegions[i].y) > 1))
concernedRegions.Add(oldActiveRegions[i]);
regionsCount = concernedRegions.Length;
//Disable all excluded regions
for (var i = 0; i < regionsCount; i++)
{
var worldMapRegion = new WorldMapRegion { value = concernedRegions[i] };
m_RegionsQuery.SetSharedComponentFilter(worldMapRegion);
commandBuffer.AddComponent<Disabled>(m_RegionsQuery);
m_RegionsQuery.ResetFilter();
}
oldActiveRegions.Dispose();
concernedRegions.Dispose();
}).Run();
}
}