i10me_Ren
@i10me_Ren (水野 雷火)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【Unity C#】スタミナの要素をプログラムしたいです

作りたいコマンド

以下のようなプログラムをUnity C#言語で制作したいです

スタミナゲージが0以上 かつ LeftCtrlが押されたら(押しっぱなし) FlagをON
FlagがONの時[指定コマンドA]を1度だけ実行

スタミナゲージが0 もしくは LeftCtrlが離されたらFlagをOFF
FlagがOFFの時[指定コマンドB]を一度だけ実行

[指定コマンドA]  (スタミナ値0まで)
(1).スピードを2.0fまで上げる
(2).スタミナゲージを1ずつ0まで下げていく
(3).1秒後に(1)にループさせる

[指定コマンドB] (スタミナ値MAXまで)
(1).スピードを1.0fに戻す
(2).スタミナゲージを1ずつ上げていく(回復)
(3).1秒後に(1)にループさせる 

自分で書いたプログラム

    float speed;
    float staminaGage;
    bool dashJudge = false; //dashしているかの判定

//ダッシュ
        if (Input.GetKey(KeyCode.LeftControl)) {  //LeftControlが押されているとき
                if(!dashJudge){
                    dashJudge = true;  //判定をTrue
                    StartCoroutine(dashA()); //dashAに移動
                }
        }else if(Input.GetKeyUp ( KeyCode.LeftControl )) {
                dashJudge = false; //判定をFalse
                StartCoroutine(dashB()); //dashBに移動
        }


    //ダッシュしてるとき
    IEnumerator dashA() {
        if(dashJudge == true){
            speed = 2.0f; //スピードを速く
            while(staminaGage > 0.0f){
                yield return new WaitForSeconds(1); //1秒待機(コルーチン)
                staminaGage -= 1.0f; //スタミナを1消費
                print(staminaGage); //現在のスタミナを表示
            }
        }
    }

    //ダッシュしてないとき
    IEnumerator dashB() {
        speed = 1.0f;
        while(staminaGage < 5.0f){
            yield return new WaitForSeconds(1); //1秒待機(コルーチン)
            staminaGage += 1.0f; //スタミナを1回復
            print(staminaGage); //現在のスタミナを表示
        }
    }

発生している問題

LeftCtrlを押している間は1秒ごとに数値が減っていっているが
離した際に数値が1増えて1減る,1増えて1減るという無限ループに入ってしまいます

914_20220607212304.png

0

3Answer

追記
0になるまでLeftCtrlを押しといて、0になったときに離すときちんと数字が増えていきます。
ただし、0になった際スピードが1.0fにならず2.0fのままです。

0Like

dashA()のwhileの条件がstaminaGage > 0.0fになっているので、
LeftCtrlを離した後も、このwhileが動き続けているからではないかと思います。
while(staminaGage > 0.0f && dashJudge == true)にすると止まるようになるかと思います。

ただし、0になった際スピードが1.0fにならず2.0fのままです。

こちらに関してもdashA()内で、
staminaGage > 0.0fならspeed = 2.0fそれ以外はspeed = 1.0f
とすると解決しそうです。

0Like
  • Dash が押される → ダッシュ開始
  • Dash が離される → ダッシュ終わり
  • スタミナがなくなる → ダッシュ終わり

という処理にすれば整然とすると思います。

using UnityEngine;
using UnityEngine.UI;

public class Dash : MonoBehaviour
{
    [SerializeField] float _staminaConsumeRatio = 50f;
    [SerializeField] float _staminaRecoveryRatio = 20f;
    [SerializeField] float _maxStamina = 100f;
    [SerializeField] Slider _staminaGauge;
    float _stamina;
    bool _isDashing;

    void Start()
    {
        _stamina = _maxStamina;

        if (_staminaGauge)
        {
            _staminaGauge.maxValue = _maxStamina;
        }
    }

    void Update()
    {
        if (Input.GetButtonDown("Fire1"))   // LeftCtrl pressed
        {
            print("Dash started.");
            _isDashing = true;
            // ここでスピードを上げる
        }
        else if (Input.GetButtonUp("Fire1"))   // LeftCtrl released
        {
            print("Dash released.");
            _isDashing = false;
            // ここでスピードを落とす
        }

        if (_isDashing)
        {
            if (_stamina > 0)
            {
                _stamina -= _staminaConsumeRatio * Time.deltaTime;
            }
            else
            {
                print("exhausted.");
                _isDashing = false;
                // ここでスピードを落とす
            }
        }
        else if (_stamina < _maxStamina)
        {
            _stamina += _staminaRecoveryRatio * Time.deltaTime;
        }

        if (_staminaGauge)
        {
            _staminaGauge.value = _stamina;
        }
        else
        {
            print($"stamina: {_stamina.ToString("0.0")}");
        }
    }
}
0Like

Your answer might help someone💌