c# - 第一次完成后如何重新启动协程?
问题描述
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Teleporting : MonoBehaviour
{
public List<GameObject> teleporters = new List<GameObject>();
public GameObject objectToTeleportMaterial;
public float fadeSpeed = 0.1f;
public bool toTeleport = false;
private List<Vector3> teleportersPositions = new List<Vector3>();
private bool teleported = false;
private Material material;
private GameObject myother;
private List<Component> components = new List<Component>();
// Start is called before the first frame update
void Start()
{
teleporters.AddRange(GameObject.FindGameObjectsWithTag("Teleporter"));
if (teleporters.Count > 0)
{
foreach (GameObject teleporter in teleporters)
{
teleportersPositions.Add(teleporter.transform.position);
}
}
}
private void OnTriggerEnter(Collider other)
{
myother = other.gameObject;
material = objectToTeleportMaterial.GetComponent<Renderer>().material;
TeleportingVisualEffect(material, 0f, 5f);
}
// Update is called once per frame
void Update()
{
if(teleported == true)
{
myother.GetComponent<NavMeshAgent>().enabled = false;
myother.transform.position = teleporters[0].transform.position;
TeleportingVisualEffect(material, 1f, 5f);
teleported = false;
}
}
private void TeleportingVisualEffect(Material material, float fadeTargetOpacity, float fadeDuration)
{
MaterialExtensions.ToFadeMode(material);
StartCoroutine(FadeTo(material, fadeTargetOpacity, fadeDuration));
}
// Define an enumerator to perform our fading.
// Pass it the material to fade, the opacity to fade to (0 = transparent, 1 = opaque),
// and the number of seconds to fade over.
IEnumerator FadeTo(Material material, float targetOpacity, float duration)
{
// Cache the current color of the material, and its initiql opacity.
Color color = material.color;
float startOpacity = color.a;
// Track how many seconds we've been fading.
float t = 0;
while (t < duration)
{
// Step the fade forward one frame.
t += Time.deltaTime;
// Turn the time into an interpolation factor between 0 and 1.
float blend = Mathf.Clamp01(t / duration);
// Blend to the corresponding opacity between start & target.
color.a = Mathf.Lerp(startOpacity, targetOpacity, blend);
// Apply the resulting color to the material.
material.color = color;
// Wait one frame, and repeat.
yield return null;
}
if(targetOpacity == 1)
{
myother.GetComponent<NavMeshAgent>().enabled = false;
}
teleported = true;
}
第一次协程在 OnTriggerEnter 内部启动并将 alpha 颜色更改为 0 第二次是在 Update 中并将 alpha 颜色更改为 1
但是有一个问题。更新中的协程重新开始,在将 alpha 颜色更改为 1 后,传送始终为真。
是什么也使 NavMeshAgent 组件永远不会再次启用。
解决方案
最简单的方法是在您的协程本身中放置一个循环,只需将整个事情包装在一个 do-while 语句中,并在/如果您需要通过 while 条件退出协程。
或者,StartCoroutine 方法返回实际运行的协程的值,您可以存储并检查协程是否已完成返回值。
推荐阅读
- svelte - 如何获得 Svelte 组件名称?
- mysql - 合并两个表列而不进行连接查询
- javascript - 多个组件状态的反应钩子没有更新
- cypress - 在柏树中编辑 html
- python - django 模型中的用户输入和文本选择
- svelte - 如何从 SvelteKit 中的端点获取主机名?
- kubernetes - 同一个 PersistentVolume 'pv' 可以绑定到不同命名空间中的多个 PersistentVolumeClaims 'pvc' 吗?
- mysql - mysql中2个表之间的减法
- laravel - Laravel artisan 迁移命令行和 Artisan::call 之间的差异
- react-native - Lottie Animation - 反应本机应用程序上未显示颜色