简体   繁体   中英

How can I start a coroutine again when the first time finish?

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;
    }

First time the coroutine start inside the OnTriggerEnter and change the alpha color to 0 The second time is in the Update and change the alpha color to 1

but there is a problems. The coroutine in the Update is start over again teleported is true all the time after it's changing the alpha color to 1.

what also make that the NavMeshAgent component will never be enabled true again.

The easiest way would be to put a loop in your Coroutine itself, just wrap the whole thing in a do-while statement and exit the coroutine when/if you need to via the while condition.

alternatively, the StartCoroutine method returns a value of the actual coroutine running, which you can store and check if the coroutine has finished that the returned value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM