为了账号安全,请及时绑定邮箱和手机立即绑定

团结| 每次执行后协程加速

团结| 每次执行后协程加速

C#
MM们 2023-09-24 11:19:25
我的协程在玩家死后淡出他们,// Fade out ragdollIEnumerator RagdollFade(){    yield return new WaitForSeconds(3f);    while (startingColour.a > 0.0f)    {        headSR.color = new Color(headSR.color.r, headSR.color.g, headSR.color.b, headSR.color.a - (Time.deltaTime / 1.5f));        bodySR.color = new Color(bodySR.color.r, bodySR.color.g, bodySR.color.b, bodySR.color.a - (Time.deltaTime / 1.5f));        leftArmSR.color = new Color(leftArmSR.color.r, leftArmSR.color.g, leftArmSR.color.b, leftArmSR.color.a - (Time.deltaTime / 1.5f));        rightArmSR.color = new Color(rightArmSR.color.r, rightArmSR.color.g, rightArmSR.color.b, rightArmSR.color.a - (Time.deltaTime / 1.5f));        leftLegSR.color = new Color(leftLegSR.color.r, leftLegSR.color.g, leftLegSR.color.b, leftLegSR.color.a - (Time.deltaTime / 1.5f));        rightLegSR.color = new Color(rightLegSR.color.r, rightLegSR.color.g, rightLegSR.color.b, rightLegSR.color.a - (Time.deltaTime / 1.5f));        yield return null;    }}每次执行后都会加速。例如,第一次调用协程时一切正常,3 秒后播放器淡出。然而,下一次调用时,在淡入淡出之前不要过去3秒,下一次甚至更短的时间,等等。startingColour在 Start() 函数中设置。
查看完整描述

2 回答

?
胡子哥哥

TA贡献1825条经验 获得超6个赞

看起来你的startingColour.a总是比这个大,0所以while循环永远不会结束,你的协程会永远运行。如果没有看到其余代码,很难判断。

因此,如果你第二次启动它,你现在有两个例程并行运行 => 现在每一帧你将 alpha 减少两倍..然后三倍..等等,并且它也不会在第一次调用之前等待 3 秒例程已经在运行while循环,因此它们会继续减少 alpha。


当开始新的例程时,您可以使用StopAllCoroutinesStopCoroutine来中断任何仍在运行的例程。但这实际上更像是一种肮脏的解决方法。


我宁愿解决实际问题并确保您的 while 循环返回,这目前不太可能发生,因为您似乎没有startColor.a任何改变。

或者添加一个根本不允许并行例程的标志,例如

private bool isFading;


IEnumerator RagdollFade()

{

    if(isFading) yield brake;


    // prevents other routines

    isFading = true;


    ...


    // reset the flag once routine is finished

    isFading = false;

}

然后我还宁愿建议使用一个单一float值来进行淡入淡出,Color.Lerp例如

private bool isFading;


// you can also use a fixed duration and not pass it as parameter

// but this way you are even more flexible

IEnumerator RagdollFade(float duration)

{

    if(isFading) yield brake;


    // prevents other routines

    isFading = true;


    yield return new WaitForSeconds(3f);


    // it is more performant to gather all required information beforehand


    headStartColor = headSR.color;

    bodyStartColor = bodySR.color;

    leftArmStartColor = leftArmSR.color;

    rightArmStartColor = rightArmSR.color;

    leftLegStartColor = leftLegSR.color;

    rightLegStartColor = rightLegSR.color;


    headTargetColor = new Color(headStartColor.r, headStartColor.g, headStartColor.b, 0f);

    bodyTargetColor = new Color(bodyStartColor.r, bodyStartColor.g, bodyStartColor.b, 0f);

    leftArmTargetColor = new Color(leftArmStartColor.r, leftArmStartColor.g, leftArmStartColor.b, 0f);

    rightArmTargetColor = new Color(rightArmStartColor.r, rightArmStartColor.g, rightArmStartColor.b, 0f);

    leftLegTargetColor = new Color(leftLegStartColor.r, leftLegStartColor.g, leftLegStartColor.b, 0f);

    rightLegTargetColor = new Color(rightLegStartColor.r, rightLegStartColor.g, rightLegStartColor.b, 0f);


    var passedTime = 0f;

    while (passedTime < duration)

    {

        // get the interpolation factor from 0 to 1

        var factor = passedTime / duration;

        // for adding additional ease-in and ease-out

        // factor = Mathf.SmoothStep(0, 1, factor);


        headSR.color = Color.Lerp(headStartColor, headTargetColor, factor);

        bodySR.color = Color.Lerp(bodyStartColor, bodyTargetColor, factor);

        leftArmSR.color = Color.Lerp(leftArmStartColor, leftArmTargetColor, factor);

        rightArmSR.color = Color.Lerp(rightArmStartColor, rightArmTargetColor, factor);

        leftLegSR.color = Color.Lerp(leftLegStartColor, leftLegTargetColor, factor);

        rightLegSR.color = Color.Lerp(rightLegStartColor, rightLegTargetColor, factor);



        // avoid overshooting

        passedTime += Mathf.Min(Time.deltatime, duration - passedTime);

        yield return null;

    }


    // reset the flag once routine is finished

    isFading = false;

}

这更加灵活,您可以使用您喜欢的任何简单数学添加缓入和缓出。


查看完整回答
反对 回复 2023-09-24
?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

StopCoroutine()在启动新协程之前尝试调用。可能您有几个协程同时工作。



查看完整回答
反对 回复 2023-09-24
?
ITMISS

TA贡献1871条经验 获得超8个赞

好吧,我已经解决了这个问题,这完全是我的错。

我意识到我的另一个协程正在干扰当前的协程,所以这就是为什么StopCoroutine()添加淡入淡出检查不起作用。

抱歉,大家没有将其包含在我的问题帖子中,您可能能够更有效地帮助我。

因此,对于将来遇到奇怪的例行行为的任何人,请确保两个协程不会互相干扰。


查看完整回答
反对 回复 2023-09-24
  • 2 回答
  • 0 关注
  • 108 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信