using Unity.Collections.LowLevel.Unsafe;
// Make sure PolylinePoint and Vector2 are defined appropriately in your project.
public struct PolylinePoint
public PolylinePoint(Vector2 point, Color color, float thickness)
this.thickness = thickness;
[BurstCompile] // Optional: for further speedups
public struct UpdatePolylinePointsJob : IJobParallelFor
[ReadOnly] public NativeArray<float> data;
// Marked with NativeDisableUnsafePtrRestriction to allow passing unsafe NativeArray
[NativeDisableUnsafePtrRestriction]
public NativeArray<PolylinePoint> ptsInternal;
public Color beforeColor;
public void Execute(int i)
float t = math.remap(0, ptsInternal.Length, 0f, 1f, i);
float x = math.remap(0f, 1f, left, left + width, t);
float y = math.remap(min, max, bottom, bottom + height, d);
ptsInternal[i] = new PolylinePoint(
t < T ? beforeColor : afterColor,
public class PolylineUpdater : MonoBehaviour
// Managed array that will be “pinned”
private PolylinePoint[] _ptsInternal;
[SerializeField] private float[] data;
// These values need to be set according to your context
public float left = 0f, width = 10f, min = 0f, max = 1f;
public float bottom = 0f, height = 5f, T = 0.5f;
public Color beforeColor = Color.green, afterColor = Color.red;
public void UpdatePoints()
// Ensure our managed array is allocated with the correct length.
if (_ptsInternal == null || _ptsInternal.Length != data.Length)
_ptsInternal = new PolylinePoint[data.Length];
// Pin the managed array and create a NativeArray view without extra allocations.
fixed (PolylinePoint* ptsPtr = _ptsInternal)
// Create a NativeArray view over the pinned memory.
var nativePts = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<PolylinePoint>(
#if ENABLE_UNITY_COLLECTIONS_CHECKS
// When safety checks are enabled, assign an atomic safety handle.
NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref nativePts, AtomicSafetyHandle.Create());
// For the input data, you can create a temporary NativeArray.
// If data is large or updated frequently, consider using a persistent native container.
var nativeData = new NativeArray<float>(data, Allocator.TempJob);
// Set up the parallel job.
var job = new UpdatePolylinePointsJob
beforeColor = beforeColor,
// Schedule the job with a batch size (e.g., 64) and wait for its completion.
JobHandle handle = job.Schedule(_ptsInternal.Length, 64);
// Dispose the temporary nativeData array.
// At this point, _ptsInternal has been updated by the job.
// You can now use _ptsInternal as needed.