KeyCode.Wを押してから徐々にAudioSource.volumeを `3f` まで上げて行きたいのですが  
現状のコードではフリーズしてしまいます。

どのようにすればよいでしょうか？

```

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class PlayerManager : MonoBehaviour
    {
        private AudioSource audioSource;
        private float volumeWhile = 3f;
      
        void Start()
        {
      
            audioSource = GetComponent<AudioSource>();
        }
        // Update is called once per frame
        void Update()
        {   
            if (Input.GetKey(KeyCode.W))
            {
                if (!audioSource.isPlaying)
                {
                    while (audioSource.volume < volumeWhile)
                    {
                        audioSource.Play();
                        audioSource.volume += 0.5f;
    
                        if (audioSource.volume == volumeWhile) break;
                    }
                }
            }
            if (Input.GetKeyUp(KeyCode.W))
                {
                audioSource.Stop();
            }
        }
    }
    
```
CC BY-SA 4.0
2022-02-22T11:14:26.627
86516
2022-02-22T17:18:35.977
2022-02-22T12:30:48.570
3060
51562
question
c# unity3d
キーを押してから徐々にボリュームを上げていく方法がわかりません
`while` 文が `break` する条件で「目標の値になったら」ということで `==` での比較を行っていますが、浮動小数点同士の比較なので演算
(ここではインクリメント) をしていく過程で **誤差** が発生している可能性があります。

代わりに「目標の値を超えたら」にしてみると良いかもしれません。

```

    if (audioSource.volume >= volumeWhile) break;
    
```
CC BY-SA 4.0
2022-02-22T12:37:12.153
86517
2022-02-22T12:37:12.153
3060
86516
answer
[【Unity】キーを押してから徐々にボリュームを上げていく方法がわかりません。](https://teratail.com/questions/e32vuboauda7xj)
ではコルーチンでないものを使って問題がクローズされているので、こちらに書いておきます。なお、[AudioSource.volume の最大値は
1](https://docs.unity3d.com/ja/2019.4/ScriptReference/AudioSource-volume.html)
です。

```

    using System.Collections;
    using UnityEngine;
    
    public class PlayerManager : MonoBehaviour
    {
        [SerializeField] float _changeVolumeDelta = 0.001f;
        [SerializeField] float _changeVolumeIntervalSecond = 0.1f;
        [SerializeField] float _maxVolume = 1;
        AudioSource _audio = default;
        Coroutine _coroutine = default;
    
        void Start()
        {
            _audio = GetComponent<AudioSource>();
        }
    
        void Update()
        {
            if (Input.GetKeyDown(KeyCode.W))
            {
                // 音が「流れていない」時
                if (!_audio.isPlaying)
                {
                    if (_coroutine != null)
                    {
                        _coroutine = StartCoroutine(IncreaseVolume(_maxVolume));
                    }
                }
            }
    
            // ↓を押している間、ボリュームを下げる
            if (Input.GetKeyDown(KeyCode.DownArrow))
            {
                _coroutine = StartCoroutine(DecreaseVolume());
            }
            else if (Input.GetKeyUp(KeyCode.DownArrow))
            {
                StopCoroutine(_coroutine);
            }
        }
    
        IEnumerator IncreaseVolume(float target)
        {
            while (_audio.volume < target)
            {
                _audio.volume += _changeVolumeDelta;
                yield return new WaitForSeconds(_changeVolumeIntervalSecond);
            }
        }
    
        IEnumerator DecreaseVolume()
        {
            while (_audio.volume > 0)
            {
                _audio.volume -= _changeVolumeDelta;
                yield return new WaitForSeconds(_changeVolumeIntervalSecond);
            }
        }
    }
    
```
CC BY-SA 4.0
2022-02-22T17:18:35.977
86519
2022-02-22T17:18:35.977
48297
86516
answer