Как одновременно запустить два метода?
Подскажите пожалуйста, как сделать чтобы два метода выполнялись одновременно, при попытке через thread выбивает UnityException: get_transform can only be called from the main thread. Constructors and field initializers will be executed from the loading thread when loading a scene. Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
public class BrickCutter : MonoBehaviour
{
RaycastHit hit;
private void Update()
{
Thread CutRL = new Thread(CutterRL);
Thread CutFB = new Thread(CutterFB);
CutFB.Start();
CutRL.Start();
}
private void CutterRL()
{
RaycastHit _checkRayRight;
if (BrickFreezer.falled)
{
Physics.Raycast(transform.position + new Vector3(-Mathf.Abs(transform.localScale.x) / 2, 0, 0), Vector3.up, out _checkRayRight, Mathf.Infinity);
if (_checkRayRight.transform != null)
{
Physics.Raycast(transform.position + new Vector3(-Mathf.Abs(transform.localScale.x) / 2, 0, 0), Vector3.up, out hit, Mathf.Infinity);
Spawner.lastBrickScaleX = hit.transform.localScale.x - Mathf.Abs(hit.transform.position.x - transform.position.x);
hit.transform.localScale = new Vector3(Spawner.lastBrickScaleX, hit.transform.localScale.y, hit.transform.localScale.z);
hit.transform.position = new Vector3(transform.position.x - (transform.position.x - hit.transform.position.x) / 2, hit.transform.position.y, hit.transform.position.z);
Spawner.lastXPosition = hit.transform.position.x;
Spawner.lastZPosition = hit.transform.position.z;
Destroy(this);
}
else
{
Physics.Raycast(transform.position + new Vector3(Mathf.Abs(transform.localScale.x) / 2, 0, 0), Vector3.up, out hit, Mathf.Infinity);
Spawner.lastBrickScaleX = hit.transform.localScale.x-Mathf.Abs(hit.transform.position.x - transform.position.x);
hit.transform.localScale = new Vector3(Spawner.lastBrickScaleX, hit.transform.localScale.y, hit.transform.localScale.z);
hit.transform.position = new Vector3(transform.position.x - (transform.position.x - hit.transform.position.x) / 2, hit.transform.position.y, hit.transform.position.z);
Spawner.lastXPosition = hit.transform.position.x;
Spawner.lastZPosition = hit.transform.position.z;
Destroy(this);
}
}
}
private void CutterFB()
{
RaycastHit _checkRayFront;
if (BrickFreezer.falled)
{
Physics.Raycast(transform.position + new Vector3(0, 0, -Mathf.Abs(transform.localScale.z) / 2), Vector3.up, out _checkRayFront, Mathf.Infinity);
if (_checkRayFront.transform != null)
{
Physics.Raycast(transform.position + new Vector3(0, 0, -Mathf.Abs(transform.localScale.z) / 2), Vector3.up, out hit, Mathf.Infinity);
Spawner.lastBrickScaleZ = hit.transform.localScale.z - Mathf.Abs(hit.transform.position.z - transform.position.z);
hit.transform.localScale = new Vector3(hit.transform.localScale.x, hit.transform.localScale.y, Spawner.lastBrickScaleZ);
hit.transform.position = new Vector3(hit.transform.position.x, hit.transform.position.y, transform.position.z - (transform.position.z - hit.transform.position.z) / 2);
Spawner.lastXPosition = hit.transform.position.x;
Spawner.lastZPosition = hit.transform.position.z;
Destroy(this);
}
else
{
Physics.Raycast(transform.position + new Vector3(0, 0, Mathf.Abs(transform.localScale.z) / 2), Vector3.up, out hit, Mathf.Infinity);
Spawner.lastBrickScaleZ = hit.transform.localScale.z - Mathf.Abs(hit.transform.position.z - transform.position.z);
hit.transform.localScale = new Vector3(hit.transform.localScale.x, hit.transform.localScale.y, Spawner.lastBrickScaleZ);
hit.transform.position = new Vector3(hit.transform.position.x, hit.transform.position.y, transform.position.z - (transform.position.z - hit.transform.position.z) / 2);
Spawner.lastXPosition = hit.transform.position.x;
Spawner.lastZPosition = hit.transform.position.z;
Destroy(this);
}
}
}
}
Ответы (1 шт):
Использовать потоки через Thread далеко не лучшая идея (особенно в Unity). Существуют более удобные инструменты как для асинхронных, так и для параллельных вычислений.
Для асинхронности в Unity можно использовать корутины. Однако их я также не рекомендую использовать, так как корутины могут снизить читаемость кода, и работать с ними не так удобно, как с другими вариантами. Взамен, начиная с Unity 2021 (возможно и с более старшей версии) можно использовать System.Threading.Tasks.Task () или, еще лучше, подключить библиотеку UniTask.
Для параллельных вычислений можно использовать Jobs. Для рейкастов есть даже отдельный класс RaycastCommand.