Как я могу изменить свой код, чтобы использовать Unity Job System? Или же как мне оптимизировать свой код?
Я написал код для проекта Unity, который я хочу оптимизировать, используя Unity Job System. Однако я ничего не понял с документации Unity, как использовать Job System или как изменить свой код, чтобы воспользоваться его возможностями. Может ли кто-то дать совет, как я могу изменить свой код, чтобы использовать Unity Job System? Также я не буду против простых советов как оптимизировать мой довольно тормознутый код.
public class ResourceManager : MonoBehaviour
{
[SerializeField] private Pipes pipes;
[SerializeField] private Buildings buildings;
private TileBase[] directionTile;
private TileBase[][] turnPipes = new TileBase[4][];
private TileBase[] teePipes = new TileBase[4];
private TileBase crossPipe;
public Dictionary<int, Transform> _resourcesDict = new Dictionary<int, Transform>();
public Dictionary<int, Resource> _resoucresComponentDict = new Dictionary<int, Resource>();
public int resourceDictCount = 0;
private Vector3Int[] offsets = new Vector3Int[] {
new Vector3Int(0, 1, 0),
new Vector3Int(1, 0, 0),
new Vector3Int(0, -1, 0),
new Vector3Int(-1, 0, 0)
};
private CancellationTokenSource cancellationTokenSource;
private async void Awake()
{
directionTile = pipes.DirectionTile;
turnPipes[0] = pipes.TurnPipesUp;
turnPipes[1] = pipes.TurnPipesRight;
turnPipes[2] = pipes.TurnPipesDown;
turnPipes[3] = pipes.TurnPipesLeft;
teePipes = pipes.TeePipes;
crossPipe = pipes.CrossPipe;
cancellationTokenSource = new CancellationTokenSource();
await ResourceTask(cancellationTokenSource.Token);
}
private async UniTask ResourceTask(CancellationToken cancellationToken)
{
Transform[] neighborPipes = new Transform[4];
while (true)
{
if (this != null)
{
int objectsPerFrame = Mathf.CeilToInt((resourceDictCount + 50) / 5);
int objectsProcessed = 0;
for (int key = 0; key < resourceDictCount; key++)
{
if (objectsProcessed % objectsPerFrame == 0)
{
await UniTask.Yield();
}
if (_resourcesDict.TryGetValue(key, out Transform transform) && _resoucresComponentDict.TryGetValue(key, out Resource resource))
{
if (pipes._pipeGroupDict.TryGetValue(Vector3Int.FloorToInt(resource.pos), out Pipes.PipeObj pipeByPos))
{
Vector3Int cellPosition = Vector3Int.FloorToInt(resource.pos);
for (int i = 0; i < 4; i++)
{
if (pipes._pipeGroupDict.TryGetValue(cellPosition + offsets[i], out Pipes.PipeObj neiPipe)) neighborPipes[i] = neiPipe.transform;
else neighborPipes[i] = null;
}
if (resource.lastPipe != pipeByPos.transform)
{
resource.currentPipe = pipeByPos.Pipe;
resource.neighboringPipes = neighborPipes;
}
resource.lastPipe = pipeByPos.transform;
if (resource.currentPipe != null)
{
if (resource.startPipe == null)
{
resource.startPipe = resource.currentPipe;
resource.isStart = resource.currentPipe == resource.startPipe && Vector3.Distance(resource.pos, resource.currentPipe.transform.position) > 0.1f;
}
int neighbors = 0;
for (int i = 0; i < 4; i++)
{
if (resource.neighboringPipes[i] || ((i + 2) % 4 == resource.lastDirection)) neighbors++;
else if (buildings._lineGroupDict.TryGetValue(cellPosition + offsets[i], out Transform lineObject)) neighbors++;
}
if (Vector3.Distance(resource.pos, resource.targetPosition) < 0.01f || resource.targetPosition == Vector3.zero)
{
if (Enumerable.SequenceEqual(resource.neighboringPipes, neighborPipes) == false)
{
resource.currentPipe = pipeByPos.Pipe;
resource.neighboringPipes = neighborPipes;
}
if (resource.isStart)
{
resource.isStart = resource.currentPipe == resource.startPipe && Vector3.Distance(resource.pos, resource.currentPipe.transform.position) > 0.01f;
resource.targetPosition = resource.currentPipe.transform.position;
}
else if (neighbors == 2) TGP_DirectionAndTurn(resource);
else if (neighbors == 3) TGP_Tee(resource);
else if (neighbors == 4 && resource.currentPipe.currentTile == crossPipe) TGP_Cross(resource);
}
if (Vector3.Distance(resource.pos, resource.targetPosition) > 0.01f || neighbors != 1 && resource.neighboringPipes[resource.lastDirection]) MoveToCenter(resource.targetPosition, transform);
}
}
else resource.currentPipe = null;
objectsProcessed++;
}
}
}
await UniTask.Yield();
}
}
private void TGP_DirectionAndTurn(Resource r)
{
for (int i = 0; i < directionTile.Length; i++)
{
if (r.currentPipe.currentTile == directionTile[i] && r.neighboringPipes[i])
{
r.targetPosition = r.neighboringPipes[i].transform.position;
r.lastDirection = i;
break;
}
else if (i == 3 && r.currentPipe.currentTile != directionTile[i])
{
for (int j = 0; j < turnPipes[r.lastDirection].Length; j++)
{
int directionIndex = r.lastDirection % 2 == 0 ? 3 : 2;
int index = directionIndex / (directionIndex * (j % 2) + (j % 2 == 0 ? 1 : 0));
if (r.currentPipe.currentTile == turnPipes[r.lastDirection][j] && r.neighboringPipes[directionIndex == 2 && index == 1 ? 0 : index])
{
r.targetPosition = r.neighboringPipes[directionIndex == 2 && index == 1 ? 0 : index].transform.position;
r.lastDirection = directionIndex == 2 && index == 1 ? 0 : index;
}
}
}
}
}
private void TGP_Tee(Resource r)
{
int[] indices = new int[3];
var pipesOutput = r.currentPipe.PipesOutput;
for (int i = 0; i < 4; i++)
{
if (r.currentPipe.currentTile == teePipes[i])
{
int index = 0;
int direction = (r.lastDirection + 2) % 4;
for (int j = 0; j < 4; j++) if (j != direction && r.currentPipe.IsNeighbor[j] && index < 2) indices[index++] = j;
if (pipesOutput[indices[0]][indices[0]] || r.neighboringPipes[indices[0]] == false)
{
if (pipesOutput[indices[1]][indices[1]] || r.neighboringPipes[indices[1]] == false)
{
pipesOutput[indices[0]][indices[0]] = false;
pipesOutput[indices[1]][indices[1]] = false;
}
}
int indexCached = 0;
for (int j = 0; j < 2; j++)
{
indexCached = indices[j];
if (pipesOutput[indexCached][indexCached] == false && r.neighboringPipes[indexCached])
{
r.targetPosition = r.neighboringPipes[indexCached].transform.position;
r.lastDirection = indexCached;
pipesOutput[indexCached][indexCached] = true;
break;
}
}
}
}
}
private void TGP_Cross(Resource r)
{
int number = 0;
int[] indices = new int[3];
int direction = (r.lastDirection + 2) % 4;
for (int j = 0; j < 4; j++) if (j != direction) indices[number++] = j;
var pipesOutput = r.currentPipe.PipesOutput;
int count = 0;
int index = 0;
for (int i = 0; i < 3; i++)
{
index = indices[i];
if (pipesOutput[r.lastDirection][index] || r.neighboringPipes[index] == false)
{
count++;
if (count == 3) for (int j = 0; j < 4; j++) pipesOutput[r.lastDirection][j] = false;
}
}
for (int i = 0; i < 3; i++)
{
index = indices[i];
if (pipesOutput[r.lastDirection][index] == false && r.neighboringPipes[index])
{
r.targetPosition = r.neighboringPipes[index].transform.localPosition;
pipesOutput[r.lastDirection][index] = true;
r.lastDirection = index;
break;
}
}
}
private void MoveToCenter(Vector3 targetPosition, Transform transform)
{
if (targetPosition != Vector3.zero)
{
transform.localPosition = Vector3.MoveTowards(transform.localPosition, targetPosition, 5 * Time.deltaTime);
}
}
}
Я не понимаю Unity Job System, так как я не очень опытный разработчик. Кроме того, я задаюсь вопросом, можно ли использовать foreach-цикл с словарем, который был изменен в другом сценарии. Можете ли вы мне помочь с этими вопросами?