我有两个脚本,它们将做大致相同的事情,即称为协程,并慢慢恢复耐力。事情发生在第二个脚本中,当另一个每秒增加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
,以匹配您所遵循的变量大小写。