Skip to content

Instantly share code, notes, and snippets.

@jamiebrynes7
Last active September 18, 2019 13:19
Show Gist options
  • Save jamiebrynes7/a80d0b454517ae450343407ff7d4b617 to your computer and use it in GitHub Desktop.
Save jamiebrynes7/a80d0b454517ae450343407ff7d4b617 to your computer and use it in GitHub Desktop.
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Transforms;
using UnityEngine;
// TEST
namespace Tiles
{
[UpdateBefore(typeof(TileRendererSystem))]
public class RenderCullingSystem : ComponentSystem
{
private Camera camera;
private ComponentGroup visibleGroup;
private ComponentGroup notVisibleGroup;
protected override void OnCreateManager(int capacity)
{
camera = Camera.main;
visibleGroup = GetComponentGroup(ComponentType.ReadOnly<Position>(), ComponentType.ReadOnly<TileVisibleComponent>());
notVisibleGroup = GetComponentGroup(ComponentType.ReadOnly<Position>(), ComponentType.Subtractive<TileVisibleComponent>());
}
protected override void OnUpdate()
{
camera = camera ?? Camera.main;
if (camera == null)
{
return;
}
var cameraView = new CameraViewCoordinates(camera);
var bufferOne = new EntityCommandBuffer(Allocator.TempJob);
var bufferTwo = new EntityCommandBuffer(Allocator.TempJob);
var addVisibleJob = new AddVisibleJob
{
CameraView = cameraView,
Buffer = bufferOne,
Positions = notVisibleGroup.GetComponentDataArray<Position>(),
Entities = notVisibleGroup.GetEntityArray()
};
var handle = addVisibleJob.Schedule(addVisibleJob.Entities.Length, 64);
var removeVisibleJob = new RemoveVisibleJob
{
CameraView = cameraView,
Buffer = bufferTwo,
Positions = visibleGroup.GetComponentDataArray<Position>(),
Entities = visibleGroup.GetEntityArray()
};
var secondHandle = removeVisibleJob.Schedule(removeVisibleJob.Entities.Length, 64);
handle.Complete();
secondHandle.Complete();
bufferOne.Playback(EntityManager);
bufferOne.Dispose();
bufferTwo.Playback(EntityManager);
bufferTwo.Dispose();
}
[BurstCompile]
private struct AddVisibleJob : IJobParallelFor
{
public CameraViewCoordinates CameraView;
[WriteOnly] public EntityCommandBuffer.Concurrent Buffer;
[ReadOnly] public ComponentDataArray<Position> Positions;
[ReadOnly] public EntityArray Entities;
public void Execute(int index)
{
var x = Positions[index].Value.x;
var z = Positions[index].Value.z;
if (x < CameraView.MaxX && x + 1 > CameraView.MinX && z < CameraView.MaxZ && z + 1 > CameraView.MinZ)
{
Buffer.AddComponent(Entities[index], new TileVisibleComponent());
}
}
}
[BurstCompile]
private struct RemoveVisibleJob : IJobParallelFor
{
public CameraViewCoordinates CameraView;
[WriteOnly] public EntityCommandBuffer.Concurrent Buffer;
[ReadOnly] public ComponentDataArray<Position> Positions;
[ReadOnly] public EntityArray Entities;
public void Execute(int index)
{
var x = Positions[index].Value.x;
if (CameraView.MinX > x + 1 || CameraView.MaxX < x)
{
Buffer.RemoveComponent<TileVisibleComponent>(Entities[index]);
return;
}
var z = Positions[index].Value.z;
if (CameraView.MinZ > z + 1 || CameraView.MaxZ < z)
{
Buffer.RemoveComponent<TileVisibleComponent>(Entities[index]);
}
}
}
private struct CameraViewCoordinates
{
public float MinX;
public float MaxX;
public float MinZ;
public float MaxZ;
public CameraViewCoordinates(Camera camera)
{
var bottomLeft = camera.ViewportToWorldPoint(Vector3.zero);
var topRight = camera.ViewportToWorldPoint(Vector3.one);
MinX = bottomLeft.x;
MinZ = bottomLeft.z;
MaxX = topRight.x;
MaxZ = topRight.z;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment