协程 运行 时不播放动画
Animation doesn't play while coroutine is running
当我的场景开始时,我启动了一个协程来生成一个显示给用户的谜题。有时,这一代可能需要几秒钟,但通常很快。因为用户也可以从场景中刷新拼图,所以我不想来回跳到一个单独的加载场景,而是在协程 运行 时只显示一个简单的动画。我在同一个精灵上测试了两个动画:精灵的动画师和更新时的简单旋转。但是,正如标题所说,这两个都不是 运行,而协程是 运行。我可以看到该动画有效,因为协程完成后,两个动画都会开始(请参阅下面注释掉的 SetActive(false))。我怎样才能让这个动画工作?
结构是这样的:
-游戏场景
--Canvas
---PuzzleControl 游戏Object(带有 PuzzleControl 脚本)
----动画游戏Object(带有Sprite Renderer和Animator组件)
---LoadingScreen Game Object(带有 LoadingAnimation 脚本)
public class PuzzleControl : MonoBehaviour
{
private PuzzleBuilder builder;
void Start()
{
builder = this.gameObject.AddComponent<PuzzleBuilder>();
LoadingScreen.SetActive(true);
StartCoroutine(builder.Refresh());
}
public void RebuildPuzzle()
{
LoadingScreen.SetActive(true);
StartCoroutine(builder.Refresh());
}
public void BuildComplete()
{
// This will be called by our builder -- currently turned off
//LoadingScreen.SetActive(false);
}
}
public class LoadingAnimation : MonoBehaviour
{
public GameObject animation;
private float rotateSpeed = 200f;
// Update is called once per frame
void Update()
{
animation.GetComponent<Transform>().Rotate(new Vector3(0f,0f, rotateSpeed * Time.deltaTime));
}
}
这是一个常见的误解,协程实际上并不 运行 在一个单独的线程上,所以如果你有很多计算要做,你需要将它移到任务中并 运行 它在线程池上,否则 Unity 在执行此工作时仍会冻结。协程仅 return 控制 cpu 当它们屈服时,每个帧统一将重新进入它停止的协程,这给出了代码的错觉 运行ning 同时 when实际上,它只是使用 yield 关键字被切成块。
将事物移动到线程中的一个限制是,作为一般规则,您实际上不能接触任何属于 Unity 引擎的部分,因此您需要收集所需的数据,然后将其发送给线程进行计算,然后在完成后将更改应用于场景。
这里有一个简单的例子,说明如何将长 运行ning 计算发送到一个单独的线程(或至少将其并行化,因为 C# 会将其发送到线程池以处理分配):
using System.Threading.Tasks;
void Start()
{
// send it
var taskHandle = Task<MapBuildData>.Run(DoLongBuildCalculation).ContinueWith(OnBuildComplete);
}
MapBuildData DoLongBuildCalculation()
{
// do long calculation.
return result;
}
void OnBuildComplete(Task<MapBuildData> buildTask)
{
if(buildTask.IsFaulted || buildTask.IsCanceled)
{
// handle it.
}
// do something in with buildTask.Result
}
编辑:为澄清起见,您不应在 DoLongBuildCalculation() 内部与 Unity 对象交互。
当我的场景开始时,我启动了一个协程来生成一个显示给用户的谜题。有时,这一代可能需要几秒钟,但通常很快。因为用户也可以从场景中刷新拼图,所以我不想来回跳到一个单独的加载场景,而是在协程 运行 时只显示一个简单的动画。我在同一个精灵上测试了两个动画:精灵的动画师和更新时的简单旋转。但是,正如标题所说,这两个都不是 运行,而协程是 运行。我可以看到该动画有效,因为协程完成后,两个动画都会开始(请参阅下面注释掉的 SetActive(false))。我怎样才能让这个动画工作?
结构是这样的:
-游戏场景
--Canvas
---PuzzleControl 游戏Object(带有 PuzzleControl 脚本)
----动画游戏Object(带有Sprite Renderer和Animator组件)
---LoadingScreen Game Object(带有 LoadingAnimation 脚本)
public class PuzzleControl : MonoBehaviour
{
private PuzzleBuilder builder;
void Start()
{
builder = this.gameObject.AddComponent<PuzzleBuilder>();
LoadingScreen.SetActive(true);
StartCoroutine(builder.Refresh());
}
public void RebuildPuzzle()
{
LoadingScreen.SetActive(true);
StartCoroutine(builder.Refresh());
}
public void BuildComplete()
{
// This will be called by our builder -- currently turned off
//LoadingScreen.SetActive(false);
}
}
public class LoadingAnimation : MonoBehaviour
{
public GameObject animation;
private float rotateSpeed = 200f;
// Update is called once per frame
void Update()
{
animation.GetComponent<Transform>().Rotate(new Vector3(0f,0f, rotateSpeed * Time.deltaTime));
}
}
这是一个常见的误解,协程实际上并不 运行 在一个单独的线程上,所以如果你有很多计算要做,你需要将它移到任务中并 运行 它在线程池上,否则 Unity 在执行此工作时仍会冻结。协程仅 return 控制 cpu 当它们屈服时,每个帧统一将重新进入它停止的协程,这给出了代码的错觉 运行ning 同时 when实际上,它只是使用 yield 关键字被切成块。
将事物移动到线程中的一个限制是,作为一般规则,您实际上不能接触任何属于 Unity 引擎的部分,因此您需要收集所需的数据,然后将其发送给线程进行计算,然后在完成后将更改应用于场景。
这里有一个简单的例子,说明如何将长 运行ning 计算发送到一个单独的线程(或至少将其并行化,因为 C# 会将其发送到线程池以处理分配):
using System.Threading.Tasks;
void Start()
{
// send it
var taskHandle = Task<MapBuildData>.Run(DoLongBuildCalculation).ContinueWith(OnBuildComplete);
}
MapBuildData DoLongBuildCalculation()
{
// do long calculation.
return result;
}
void OnBuildComplete(Task<MapBuildData> buildTask)
{
if(buildTask.IsFaulted || buildTask.IsCanceled)
{
// handle it.
}
// do something in with buildTask.Result
}
编辑:为澄清起见,您不应在 DoLongBuildCalculation() 内部与 Unity 对象交互。