Commit 1
This commit is contained in:
129
Assets/Scripts/Optimization/JobsMovementManager.cs
Normal file
129
Assets/Scripts/Optimization/JobsMovementManager.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using UnityEngine;
|
||||
using Unity.Collections;
|
||||
using Unity.Jobs;
|
||||
using UnityEngine.Jobs;
|
||||
using Unity.Burst;
|
||||
|
||||
namespace Elbyss.Optimization
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages 10,000+ objects using C# Job System and Burst Compiler.
|
||||
/// This avoids the overhead of 10,000 individual Update() calls.
|
||||
/// </summary>
|
||||
public class JobsMovementManager : MonoBehaviour
|
||||
{
|
||||
[Header("Spawn Settings")]
|
||||
public GameObject prefab;
|
||||
public int objectCount = 10000;
|
||||
public float spacing = 1.5f;
|
||||
|
||||
[Header("Movement Settings")]
|
||||
public float speed = 5f;
|
||||
|
||||
private TransformAccessArray transformAccessArray;
|
||||
private NativeArray<Vector3> directions;
|
||||
private bool isInitialized = false;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Optional: Start automatically or via Context Menu
|
||||
// Setup(objectCount);
|
||||
}
|
||||
|
||||
[ContextMenu("Setup 10k Objects")]
|
||||
public void InitialSetup()
|
||||
{
|
||||
Setup(objectCount);
|
||||
}
|
||||
|
||||
public void Setup(int count)
|
||||
{
|
||||
if (isInitialized) Cleanup();
|
||||
|
||||
objectCount = count;
|
||||
Transform[] transforms = new Transform[objectCount];
|
||||
directions = new NativeArray<Vector3>(objectCount, Allocator.Persistent);
|
||||
|
||||
int rowSize = Mathf.CeilToInt(Mathf.Sqrt(objectCount));
|
||||
|
||||
for (int i = 0; i < objectCount; i++)
|
||||
{
|
||||
float x = (i % rowSize) * spacing;
|
||||
float z = (i / rowSize) * spacing;
|
||||
Vector3 pos = transform.position + new Vector3(x, 0, z);
|
||||
|
||||
GameObject go = Instantiate(prefab, pos, Quaternion.identity, this.transform);
|
||||
transforms[i] = go.transform;
|
||||
|
||||
// Set alternating directions
|
||||
directions[i] = (i % 2 == 0) ? Vector3.forward : Vector3.back;
|
||||
|
||||
// CRITICAL OPTIMIZATION: Disable components that are too heavy for 10k objects
|
||||
if (go.TryGetComponent<Animator>(out var anim)) anim.enabled = false;
|
||||
if (go.TryGetComponent<CharacterController>(out var cc)) cc.enabled = false;
|
||||
|
||||
// Disable all other custom scripts
|
||||
MonoBehaviour[] scripts = go.GetComponents<MonoBehaviour>();
|
||||
foreach (var s in scripts)
|
||||
{
|
||||
if (s != this) s.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
transformAccessArray = new TransformAccessArray(transforms);
|
||||
isInitialized = true;
|
||||
Debug.Log($"Initialized {objectCount} objects with Job System.");
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
// Create the movement job
|
||||
var job = new MovementJob
|
||||
{
|
||||
DeltaTime = Time.deltaTime,
|
||||
Speed = speed,
|
||||
Directions = directions
|
||||
};
|
||||
|
||||
// Schedule the job to run in parallel on all available CPU cores
|
||||
// transformAccessArray allows the job to modify Transform data directly
|
||||
JobHandle handle = job.Schedule(transformAccessArray);
|
||||
|
||||
// This ensures the job is finished before the frame ends
|
||||
// In a real scenario, you might want to call Complete() in LateUpdate or next frame
|
||||
// but for simple movement, scheduling and completing in Update is fine.
|
||||
handle.Complete();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
private void Cleanup()
|
||||
{
|
||||
if (isInitialized)
|
||||
{
|
||||
if (transformAccessArray.isCreated) transformAccessArray.Dispose();
|
||||
if (directions.IsCreated) directions.Dispose();
|
||||
isInitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile] // This attribute tells the Burst compiler to optimize this job into machine code
|
||||
struct MovementJob : IJobParallelForTransform
|
||||
{
|
||||
public float DeltaTime;
|
||||
public float Speed;
|
||||
[ReadOnly] public NativeArray<Vector3> Directions;
|
||||
|
||||
public void Execute(int index, TransformAccess transform)
|
||||
{
|
||||
// Directly modify the transform position in parallel
|
||||
transform.position += Directions[index] * Speed * DeltaTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user