第一次完成后如何重新启动协程?

时间:2020-05-17 10:48:45

标签: c# unity3d

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之后,Update中的协程将重新传输,并且始终保持为真。

这也使NavMeshAgent组件永远不会再次启用。

1 个答案:

答案 0 :(得分:0)

最简单的方法是在Coroutine本身中放入一个循环,只需将整个内容包装在do-while语句中,并在需要时(如果需要)通过while条件退出协程。

或者,StartCoroutine方法返回实际运行的协程的值,您可以存储该值并检查协程是否完成了返回值。