Как я могу изменить свой код, чтобы использовать 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-цикл с словарем, который был изменен в другом сценарии. Можете ли вы мне помочь с этими вопросами?


Ответы (0 шт):