如何在按下和释放左移时使纹理条的长度相等?

问题描述 投票:0回答:1

我试图在按下左 shift 键以显示玩家的冲刺后绘制纹理条,在释放左 shift 键后纹理条将快速重新填充。问题是我想在重新填充之前将条延迟一秒钟(释放左移后),但是当我使用协程执行它时,如下所示:

yield return new WaitForSeconds(1);
stamina += Time.deltaTime;

酒吧的长度变长了

下图是按下左shift后的截图:

下面是松开左移后的截图:

代码如下:

float stamina = 5, maxStamina = 5;
     float walkSpeed, runSpeed;
     bool isRunning;
     Rect staminaRect;
     Texture2D staminaTexture;
 
 
     void Start () {
         walkSpeed = moveSpeed;
         runSpeed = walkSpeed * 1.5f; //1.5 multiplier to sprint instead of 3x
     }
 
 
  void FixedUpdate() {
         StartCoroutine(SprintPlayer());
     }
 
 
     void SetRunning(bool isRunning)
     {
         this.isRunning = isRunning;
         moveSpeed = isRunning ? runSpeed : walkSpeed;
     }
     
 
 IEnumerator SprintPlayer()
     {
         if (Input.GetKeyDown(KeyCode.LeftShift))
         {
             SetRunning(true);
             staminaRect = new Rect(Screen.width / 10, Screen.height * 9 / 10, Screen.width / 3, Screen.height / 50);
             staminaTexture = new Texture2D(1, 1);
             staminaTexture.SetPixel(0, 0, Color.white);
             staminaTexture.Apply();
         }
 
         if (Input.GetKeyUp(KeyCode.LeftShift))
         {
             SetRunning(false);
         }
 
         if (isRunning)
         {
             stamina -= Time.deltaTime;
             if (stamina < 0)
             {
                 stamina = 0;
                 SetRunning(false);
             }
         }
         else if (stamina < maxStamina)
         {
             yield return new WaitForSeconds(1);
             stamina += Time.deltaTime;
         }
     }
 
     void OnGUI()
     {
         float ratio = stamina / maxStamina;
         float rectWidth = ratio * Screen.width / 3;
         staminaRect.width = rectWidth;
         GUI.DrawTexture(staminaRect, staminaTexture);
     }

关于如何在按下和释放左移时使纹理条的长度相等有什么建议吗?

c# unity3d
1个回答
0
投票

需要限制

stamina
的上限值。但您似乎也误解了协程的工作原理。你真的不想在每次固定更新时都启动一个......而且你根本不需要为此使用固定更新。

像这样的东西应该可以解决问题

Coroutine staminaRecoveryCoroutine;

// don't look for input in fixed update
void Update()
{
    if (Input.GetKeyDown(KeyCode.LeftShift))
    {
        if(staminaRecoveryCoroutine != null)
        {
            StopCoroutine(staminaRecoveryCoroutine);
            staminaRecoveryCoroutine = null; // just to be explicit
        }

        stamina = Mathf.Clamp(stamina - Time.deltaTime, 0, maxStamina);
    }
    else
    {
        if(staminaRecoveryCoroutine == null)
            staminaRecoveryCoroutine = StartCoroutine(staminaRecoveryCoroutine());
    }

    UpdateStaminaDisplay();

}

private IEnumerator StaminaRecoveryCoroutine()
{
    yield return new WaitForSeconds(1);
    while(stamina < maxStamina)
    {
        stamina = Mathf.Clamp(stamina + Time.deltaTime, 0, maxStamina);
        yield return null; // wait for next frame
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.