public struct AdvancedMeshJob : IJob
{
[NativeDisableUnsafePtrRestriction]
public IntPtr meshDataPtr;
public float deltaTime;
public void Execute()
{
var cache = (MeshDataCache)GCHandle.FromIntPtr(meshDataPtr).Target;
for (int i = 0; i < cache.vertices.Length; i++)
{
// Считаем расстояние от центра для каждой вершины
float distanceFromCenter = Mathf.Sqrt(
cache.vertices[i].x * cache.vertices[i].x +
cache.vertices[i].z * cache.vertices[i].z
);
// Создаём повторяющуюся волну на основе расстояния
float repeatingDistance = (distanceFromCenter + deltaTime) % 1.0f;
// Применяем кривую к Y-координате
cache.vertices[i].y = cache.curveY.Evaluate(repeatingDistance) * 4f;
}
}
}
public class MeshDataCache
{
public Vector3[] vertices;
public AnimationCurve curveY;
}
public class TestMeshInJobs : MonoBehaviour
{
[SerializeField] private AnimationCurve curveX;
[SerializeField] private AnimationCurve curveY;
private Mesh targetMesh;
private MeshDataCache meshCache;
private GCHandle meshHandle;
private IntPtr meshPtr;
private AdvancedMeshJob job;
private JobHandle jobHandle;
void Start()
{
targetMesh = GetComponent<MeshFilter>().mesh;
meshCache = new MeshDataCache
{
vertices = targetMesh.vertices,
};
meshHandle = GCHandle.Alloc(meshCache, GCHandleType.Pinned);
meshPtr = (IntPtr)meshHandle;
job = new AdvancedMeshJob
{
meshDataPtr = meshPtr,
deltaTime = Time.time // Используем time вместо deltaTime для волны
};
StartCoroutine(CorrutineTest());
}
public IEnumerator CorrutineTest()
{
while(true)
{
job.deltaTime = Time.time;
jobHandle = job.Schedule();
yield return new WaitForSeconds(0.05f);
jobHandle.Complete();
targetMesh.SetVertices(meshCache.vertices);
}
}
void OnDestroy()
{
if (!jobHandle.IsCompleted)
{
jobHandle.Complete();
}
if (meshHandle.IsAllocated)
meshHandle.Free();
}
}
#ЛисыПишутКод #CSharp #Unity #GameDev #Optimization
#UnsafeCode #UnityJobs #BurstCompiler #Programming
#MultiThreading