两个脚本做"相同"的事情,但一个工作完美,另一个不完美



我有两个脚本,它们将做大致相同的事情,即称为协程,并慢慢恢复耐力。事情发生在第二个脚本中,当另一个每秒增加5 时,它会立即将耐力填充到最大值

这没有任何意义,因为我基本上是从第一个剧本中复制了第二个剧本部分,第一个非常完美。我不知道为什么

https://pastebin.com/pE1vjisj

有我所有的代码,但重要的是:

(Not working)
    void StopSprinting()
    {
        isSprinting = false;
        moveSpeed = 5;
        CallStam();
    }
    async void CallStam()
    {
        await Task.Delay(2500);
        player.SetStamBool();
    }
(Works perfectly)
    void Melee()
    {
        Vector2 attackDetectionPosition = attackDetection.position;
        Vector2 attackDirection = attackDetectionPosition + movementDirection;
 
        Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(attackDirection, attackRange, enemyLayers);
        foreach (Collider2D enemy in hitEnemies)
        {
            Debug.Log("We hit " + enemy.name);
        }
 
        if (player.CurrentStamina > 10)
        {
            player.CurrentStamina -= 10;
 
            //Deal Damage
 
            player.StamRegen = false;
            CallStam();
        }
        else if (player.CurrentStamina > 0)
        {
            //Deal half damage
            player.StamRegen = false;
            CallStam();
        }
    }
    async void CallStam()
    {
        await Task.Delay(2500);
        player.SetStamBool();
    }
    public void SetStamBool()
    {
        StamRegen = true;
        StartCoroutine(RegenerateStamina());
    }
    IEnumerator RegenerateStamina()
    {
        while (StamRegen == true && CurrentStamina < MaxStamina)
        {
            yield return new WaitForSeconds(1);
            CurrentStamina += 5;
        }
        if (CurrentStamina > MaxStamina)
        {
            int subtractionAmount = CurrentStamina - MaxStamina;
            CurrentStamina -= subtractionAmount;
        }
    }

抱歉,如果我有一段时间没有回复

首先:这些不是在做同样的事情!在一个帽子是工作你设置

player.StamRegen = false;

在另一个程序中,你忘记了这一点,所以有可能另一个例程仍在同时运行。

通常情况下,你可能会被多个并行的runnin例程所终结!


不管怎样,异步调用的混合都不好!我宁愿明确地中断任何正在运行的Coroutine,并简单地将初始延迟放入例程本身!

在播放器中有

// holds the currently running routine
private Coroutine _currentStaminaRegenaration;
public void RegenerateStamina(float initialDelay)
{
// if there is already a routine running stop it
if(_currentStaminaRegenaration != null)
{
StopCoroutine(_currentStaminaRegenaration);
}
_currentStaminaRegenaration = StartCoroutine(RegenerateStaminaRoutine(initialDelay));
}
IEnumerator RegenerateStaminaRoutine(float initialDelay)
{
// before starting the regeneration first run your initial delay
yield return new WaitForSeconds(initialDelay);
while (CurrentStamina < MaxStamina)
{
yield return new WaitForSeconds(1);
CurrentStamina += 5;
}
// Instead of your complex check and subtraction simply use 
CurrentStamina = Mathf.Min(CurrentStamina, MaxStamina);
// never sure if this is needed but just in case reset
_currentStaminaRegenaration = null;
}

现在到处都是,而不是

player.StamRegen = false;
CallStam();

你所需要做的就是打电话给

player.RegenerateStamina(2.5f);

如果2.5f秒在任何地方都是相同的延迟,那么你也可以直接将其编码到Coroutine本身中,那么你甚至不需要将其作为参数传入。

您的问题很可能是StopSprinting函数被反复调用,这使得WaitForSeconds变得多余。你需要找到一种只触发协程函数一次的方法,这里是我的建议:

public void SetStamBool()
{
if(!StamRegen){
StamRegen = true;
StartCoroutine(RegenerateStamina());
}
}

运行显然应该将StamRegen设置为false,以便该逻辑正常工作。

顺便说一句,你应该知道你可以单独使用布尔值作为条件。所以CCD_ 5和CCD_。此外,请对所有变量保持相同的大小写约定,不要将它们与函数名或类混合,因此StamRegen应该是camelCasestamRegen,以匹配您所遵循的变量大小写。

相关内容

  • 没有找到相关文章

最新更新