Как использовать потоки с transform

Рейтинг: 0Ответов: 0Опубликовано: 02.02.2023

Делаю майнкрафт, в сам майкнрафт я не играю, а делаю просто для прокачки скила

(звучит как отмаска =) )

Попробовал использовать потоки в игре, сделал с помощью

Thread thread = new Thread(() => {...});
thread.Start();

После добавления я увидел ошибку:

UnityException: get_transform can only be called from the main thread.

После 5 секунд перевода я узнал что: получение трансформа можно вызвать только из главного потока.

Как можно это пофиксить? Я что-то слышал про "что-то там Jobs" который позволяет использовать трансформы. Чтобы было подробней лучше я оставлю код:

using System.Threading;
using UnityEngine;

public class ChunkGenerate : MonoBehaviour
{
    // private
    private const byte GrassHeight = 1;
    private const byte WaterHeight = 0;

    private float _chanceToSpawn;

    [Header("Scripts")]
    [SerializeField] private WorldData _worldData;

    private void Start()
    {
        Generate();
    }

    #region generate world
    private void Generate()
    {
        Thread thread = new Thread(() => 
        {
            for (float x = transform.position.x; x < transform.position.x + _worldData.chunkWidth; x++)
            {
                for (float z = transform.position.z; z < transform.position.z + _worldData.chunkWidth; z++)
                {
                    float height = Mathf.PerlinNoise(x * _worldData.amplitude, z * _worldData.amplitude) * _worldData.terrainForce;

                    for (byte y = 0; y < height; y++)
                    {
                        Vector3 position = new Vector3(x, y, z);
                        position = GenerateAtHeight((byte)height, y, position);

                        GenerateTrees(position);
                    }
                }
            }
        });

        thread.Start();
    }

    private Vector3 GenerateAtHeight(byte height, byte y, Vector3 position)
    {
        if (height == WaterHeight)
        {
            CreateVoxel(position, _worldData.voxels[(byte)VoxelIndex.Water]);
        }
        else if (height - y < GrassHeight)
        {
            CreateVoxel(position, _worldData.voxels[(byte)VoxelIndex.Grass]);
        }
        else
        {
            CreateVoxel(position, _worldData.voxels[(byte)VoxelIndex.Dirt]);
        }

        return position;
    }
    #endregion

    #region trees
    private void GenerateTrees(Vector3 position)
    {
        Ray ray = new Ray(position, position + Vector3Int.up);

        if (Physics.Raycast(ray, out var hit, 1))
        {
            if(hit.collider.CompareTag("Voxel"))
            {
                Destroy(hit.collider.gameObject);
                GenerateLogs(position);
            }
        }
        else
        {
            GenerateLogs(position);
        }
    }

    private void GenerateLogs(Vector3 position)
    {
        _chanceToSpawn = Random.Range(0f, 1f);

        if (_chanceToSpawn >= _worldData.treeChance[0] && _chanceToSpawn < _worldData.treeChance[1])
        {
            int treeHeight = Random.Range(_worldData.minTreeHeight, _worldData.maxTreeHeight);

            Vector3 woodPosition = new Vector3();

            for (byte height = 0; height <= treeHeight; height++)
            {
                woodPosition = position + Vector3.up * height;
                CreateVoxel(woodPosition, _worldData.voxels[(byte)VoxelIndex.Log]);
            }

            GenerateLeaves(woodPosition);
        }
    }

    private void GenerateLeaves(Vector3 position)
    {
        CreateVoxel(position + Vector3Int.up, _worldData.voxels[(byte)VoxelIndex.Leaves]);
        CreateVoxel(position + Vector3Int.left, _worldData.voxels[(byte)VoxelIndex.Leaves]);
        CreateVoxel(position + Vector3Int.back, _worldData.voxels[(byte)VoxelIndex.Leaves]);
        CreateVoxel(position + Vector3Int.right, _worldData.voxels[(byte)VoxelIndex.Leaves]);
        CreateVoxel(position + Vector3Int.forward, _worldData.voxels[(byte)VoxelIndex.Leaves]);
    }
    #endregion

    #region create
    private void CreateVoxel(Vector3 position, GameObject voxel)
    {
        Transform chunkVoxel = Instantiate(voxel, position, voxel.transform.rotation).transform;

        chunkVoxel.parent = transform;
    }
    #endregion
}

Ответы

Ответов пока нет.