【问题标题】:CoRoutine Not Restarting Properly协同程序未正确重启
【发布时间】:2022-06-29 04:24:52
【问题描述】:

我有几行代码应该让球(Spark)从一个位置移动到另一个位置,然后当它到达最后一个可用位置时,它会传送回起点。但是它似乎不起作用,它只是停在给定的最后一个位置。 这是代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
        {
            int pointCount;
            public Transform point1, point2;
            public float velocity;
            float increment;
            float time, incrementation;
            [SerializeField] private Transform A,B,C,D,E,F,G,H,I,J;
            [SerializeField] private List<Transform> movePoints; 
            [SerializeField] private Transform Spark;
            // Start is called before the first frame update
            void Start()
            {
                movePoints.Add(A);
                movePoints.Add(B);
                movePoints.Add(C);
                movePoints.Add(D);
                movePoints.Add(E);
                movePoints.Add(F);
                movePoints.Add(G);
                movePoints.Add(H);
                movePoints.Add(I);
                movePoints.Add(J);
                StartCoroutine("Movespark");
    
    
    }

    // Update is called once per frame
    void Update()
    {
        Spark.position = Vector3.Lerp(point1.position, point2.position, incrementation);
        incrementation += increment * Time.deltaTime;

    }
    IEnumerator Movespark(){
        pointCount++;
        var x = movePoints.Count;
        incrementation = 0;
        point1 = movePoints[pointCount];
        if(pointCount < x){
            point1 = movePoints[pointCount];
            point2 = movePoints[pointCount+ 1];
        }
        if(pointCount >= x){
            pointCount = 0;
            StartCoroutine("Movespark");
            yield return null;
        }
            
        float distance = Vector3.Distance(point1.position, point2.position);
        increment = 1/(distance/velocity);
        yield return new WaitUntil(() => point2.position.x <= Spark.position.x);
        if(pointCount >= x)
            pointCount = 0;
        StartCoroutine("Movespark");
            
    }
}

如果有人知道如何进行这项工作,将不胜感激。

【问题讨论】:

标签: c# unity3d


【解决方案1】:
yield return Movespark();

但是有一个Coroutine Limit

请注意,有一个协程限制,如果您达到此限制,一些协程将不会触发或失败,如果您有这样的嵌套协程,则会导致非常奇怪且难以追踪的行为。

一个非常简单的选择是这样的:

    bool canMoveSpark = true;

    void Update()
    {
        if (canMoveSpark) {
            StartCoroutine(Movespark());
        }
    }

    IEnumerator Movespark(){
        canMoveSpark = false;      

        // Your code ...

        canMoveSpark = true;       
    }

与问题无关,但您似乎有这个:

        if(pointCount >= x){
            pointCount = 0;
            StartCoroutine("Movespark");
            yield return null; // Waits a frame.
        }

如果您希望“退出”协程,请改用yield break


// Seems Unnecessary
[SerializeField] private Transform A,B,C,D,E,F,G,H,I,J;

// Shows up in inspector, so just assign points 'A-J' here.
[SerializeField] private List<Transform> movePoints; 

但是,出于任何需要将它们分开的原因,您可以改为这样做:

[SerializeField] private Transform[] points;
[SerializeField] private List<Transform> movePoints; 

// ...

void Start(){
    foreach (var point in points){
        movePoints.Add(point);
    }
}

// ...

【讨论】:

  • 我不得不说,一个写得很好的答案,非常感谢您提供的其他提示。我已经实现了所有这些,它使代码更容易,并且不再跳过那一帧。在此之后,我很容易弄清楚如何正确地使一切正常工作。
猜你喜欢
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 1970-01-01
  • 2019-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多