我有一个游戏,我正在开发的团结,那里的AI正在做大量的计算,当它是它的时候。它搜索深度1,然后2,然后3等位置。在每个深度之间,我想实例化一个游戏对象,并提供有关UI深度的信息。问题是,在AI完全完成之前,什么都不会发生,然后所有的项目都一次被添加。下面是一些更好地解释的代码:
private void AIMakeMove()
{
for (int currentDepth = 1; currentDepth < maxDepth + 1; currentDepth++)
{
SearchPosition(currentDepth);
}
}
private void SearchPosition(int _currentDepth)
{
// Search the position to the given depth
score = Negamax(_currentDepth);
// Print things PROBLEM HERE
GameObject printItem = Instantiate(printItemPrefab, printItemParent.transform);
Debug.Log(_currentDepth);
}我也尝试了一个简单的Debug.Log,而不是实例化,但同样的事情发生,然后,所有打印到控制台后,AI是完成其思维过程。
为什么我的UI不更新信息?我告诉它在运行第一次深度为0的迭代之后创建一些东西,但是它跳过了这个步骤,转而继续深度2。有人能告诉我如何在每个深度之间获取信息吗?
发布于 2022-02-07 09:10:06
问题是在人工智能完全完成之前什么都不会发生。
好的,只有当统一主线程被允许完成一个框架时,UI才会更新。
但是,您将阻塞主线程,直到所有迭代完成为止。
如果在每个实例化之间阻塞是可以的,那么只需使用柯鲁丁并执行以下操作
private void AIMakeMove()
{
StartCoroutine(AIMakeMoveRoutine());
}
private IEnuemrator AIMakeMoveRoutine()
{
for (int currentDepth = 1; currentDepth < maxDepth + 1; currentDepth++)
{
SearchPosition(currentDepth);
// This now tells Unity to "interrupt" this routine here
// render the current frame and continue from here in the next frame
yield return null;
}
}
private void SearchPosition(int _currentDepth)
{
score = Negamax(_currentDepth);
GameObject printItem = Instantiate(printItemPrefab, printItemParent.transform);
Debug.Log(_currentDepth);
}这将在每次迭代完成后完成一个框架并启动一个新的框架(从而刷新UI)。
但是,如果这仍然过多地阻塞了应用程序的其余部分,那么您还应该实际运行计算异步,例如使用类似的Task
private void AIMakeMove()
{
StartCoroutine(AIMakeMoveRoutine());
}
private IEnuemrator AIMakeMoveRoutine()
{
for (int currentDepth = 1; currentDepth < maxDepth + 1; currentDepth++)
{
// you can yield another IEnuemrator -> executes this and waits for it to finish
yield return SearchPosition(currentDepth);
// This now tells Unity to "interrupt" this routine here
// render the current frame and continue from here in the next frame
yield return null;
}
}
private IEnumerator SearchPosition(int _currentDepth)
{
// run the NegamaxTask asynchronously in the background
var task = Task.Run(() => Negamax(_currentDepth));
// wait for the task to finish
while(!task.IsCompleted)
{
// do nothing but skip frames to allow the rest of the application to run smoothly
yield return null;
}
// If you do nothing else inside the loop this could also be written as
//yield return new WaitWhile(() => !task.IsComoleted);
// or
//yield return new WaitUntil(() => task.IsCompleted);
// since the task is already finished it is save / non-blocking to access the result now
score = task.Result;
var printItem = Instantiate(printItemPrefab, printItemParent.transform);
Debug.Log(_currentDepth);
}现在,这允许您的应用程序以正常的帧率继续运行,而在后台,您需要进行大量的计算,并在迭代完成时偶尔获得一个结果。
发布于 2022-02-06 16:52:43
尝试使用线程
private void AIMakeMove()
{
new System.Threading.Thread(() =>
{
for (int currentDepth = 1; currentDepth < maxDepth + 1; currentDepth++)
{
SearchPosition(currentDepth);
}
}).Start();
}
private void SearchPosition(int _currentDepth)
{
// Search the position to the given depth
score = Negamax(_currentDepth);
// Print things PROBLEM HERE
GameObject printItem = Instantiate(printItemPrefab, printItemParent.transform);
Debug.Log(_currentDepth);
}https://stackoverflow.com/questions/71009450
复制相似问题