[CreateAssetMenu(menuName = "Custom/Editable Wrapped Gradient")]
public class EditableWrappedGradient : ScriptableObject
// Use Unity's Gradient for editor editing.
public Gradient gradient = new Gradient();
// Native representation for Burst jobs.
private NativeArray<NativeGradientKey> nativeKeys;
private bool nativeInitialized = false;
/// Convert Unity's Gradient keys to a native format.
private void InitializeNativeGradient()
// Use the color keys from the built-in gradient.
GradientColorKey[] colorKeys = gradient.colorKeys;
nativeKeys = new NativeArray<NativeGradientKey>(colorKeys.Length, Allocator.Persistent);
for (int i = 0; i < colorKeys.Length; i++)
GradientColorKey key = colorKeys[i];
nativeKeys[i] = new NativeGradientKey(key.time, key.color);
nativeInitialized = true;
/// Retrieve the Burst-friendly native gradient.
public NativeGradient GetNativeGradient()
InitializeNativeGradient();
return new NativeGradient(nativeKeys);
/// Dispose of native memory when no longer needed.
private void DisposeNativeGradient()
if (nativeInitialized && nativeKeys.IsCreated)
nativeInitialized = false;
// In play mode, initialize immediately.
if (Application.isPlaying)
InitializeNativeGradient();
// This method is called whenever a property is changed in the editor.
private void OnValidate()
// If in play mode, update the native data.
if (Application.isPlaying)
InitializeNativeGradient();
// Burst-friendly native key.
public struct NativeGradientKey
public NativeGradientKey(float time, Color color)
this.color = new float4(color.r, color.g, color.b, color.a);
// Burst-friendly native gradient with evaluation.
public struct NativeGradient
public NativeArray<NativeGradientKey> keys;
public NativeGradient(NativeArray<NativeGradientKey> keys)
public float4 Evaluate(float time)
time = math.clamp(time, 0f, 1f);
return new float4(0f, 0f, 0f, 0f);
NativeGradientKey prev = keys[0];
for (int i = 1; i < count; i++)
NativeGradientKey next = keys[i];
float t = math.unlerp(prev.time, next.time, time);
return math.lerp(prev.color, next.color, t);
return keys[count - 1].color;