Reputation: 36
I’m currently building a navigation system in Unity ECS 1.3.5(Im new) and am experiencing some performance issues. The system relies on IJobEntity jobs and BufferLookup to manage pathfinding calculations for entities, and I’m finding that both the scheduling strategy and component data access patterns may not be as efficient as they could be. I’m looking for advice on how to better structure job dependencies, optimize buffer access, and minimize memory allocations. I would appreciate any and all help.
using Unity.Entities;
using Unity.Collections;
using Unity.Mathematics;
using Unity.Transforms;
using Unity.Burst;
using Unity.Jobs;
using Unity.Physics;
[BurstCompile]
[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
public partial struct NavSystem : ISystem
{
private BufferLookup<PatherWayPoint> waypointLookup;
public void OnCreate(ref SystemState state)
{
waypointLookup = state.GetBufferLookup<PatherWayPoint>(true);
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
waypointLookup.Update(ref state);
MovePathersWithPhysics moveJob = new MovePathersWithPhysics
{
waypoints = waypointLookup,
};
//moveJob.ScheduleParallel();
JobHandle jobHandle = moveJob.Schedule(state.Dependency);
jobHandle.Complete();
}
[BurstCompile]
private partial struct MovePathersWithPhysics : IJobEntity
{
[ReadOnly] public BufferLookup<PatherWayPoint> waypoints;
private void Execute([ChunkIndexInQuery] int chunkIndexInQuery, Entity entity, ref LocalTransform transform, ref Pather pather, ref PhysicsVelocity velocity)
{
// Exit if path is not calculated or completed
float3 pos = transform.Position;
if (!pather.pathCalculated || pather.pathCompleted)
{
velocity.Linear = new float3(velocity.Linear.x, 0f, velocity.Linear.z);
transform.Position = new float3(pos.x, 0, pos.z);
velocity.Angular = float3.zero;
transform.Rotation = quaternion.identity;
return;
}
// Attempt to get the waypoint buffer for this entity
if (!waypoints.TryGetBuffer(entity, out DynamicBuffer<PatherWayPoint> waypointBuffer)) return;
float3 waypointPos = waypointBuffer[pather.waypointIndex].position;
// Check if close enough to the waypoint
if (math.distancesq(pos, waypointPos) <= pather.indexDistance)
{
if (pather.waypointIndex + 1 < waypointBuffer.Length)
{
pather.waypointIndex++;
}
else
{
pather.pathCompleted = true;
transform.Position = new float3(pos.x, 0, pos.z);
transform.Rotation = quaternion.EulerXYZ(0, 0, 0);
return;
}
}
// Calculate and apply movement direction and velocity
waypointPos = waypointBuffer[pather.waypointIndex].position;
float3 moveDir = math.normalize(new float3(waypointPos.x - pos.x, 0f, waypointPos.z - pos.z));
float3 newVelocity = moveDir * pather.speed;
velocity.Linear = new float3(newVelocity.x, 0, newVelocity.z); // Retain y component for physics
transform.Position = new float3(pos.x, 0, pos.z);
transform.Rotation = quaternion.EulerXYZ(0, 0, 0);
}
}
[BurstCompile]
private void OnDestroy()
{
// Add any cleanup code here if needed in future updates
}
}
Upvotes: 0
Views: 37