所以我目前正在 Unity 中开发一款恐怖游戏。目前我有一个(工作)系统 您的音量显示在 UI slider 上。比如说你很安静,这表明你在 slider 上很安静。如果您声音很大,它会显示您的声音有多大。
我的系统正在运行。但我一直在努力寻找一种方法 如果您的音量(麦克风音量)超过一定级别或响度,则会发生事件。
所以说,我想用我的声音有多大来激活游戏对象。如果我太大声,它会触发一个事件,激活该游戏对象。我想要得到的基本上是一种方法,如果 UI slider 超过所述 slider 上的某个值,就会触发事件。
我这里的代码显示了我当前拥有的所有脚本 这个系统。我非常感谢您的帮助!
https://gist.github.com/AidenStickel/3a58f497d41cd44b320fecfcc5ea850d
(忽略标记为“ScaleFromAudioClip”的脚本)
最佳答案
这是一个有趣的功能。因此,我查看了您的初始检测代码并对其进行了一些修改以提供您请求的功能。
这是我想出的代码:
public class AudioLoudnessDetection : MonoBehaviour
{
public event Action<float> BelowLowThreshold;
public event Action<float> AboveHighThreshold;
[SerializeField] private int _sampleWindow = 64;
[SerializeField] private float _lowThreshold;
[SerializeField] private float _highThreshold;
private AudioClip _microphoneClip;
private string _microphoneName;
private bool _listening;
private float _currentLoudness;
public float lowThreshold => _lowThreshold;
public float highThreshold => _highThreshold;
public bool isListening=> _listening;
public float currentLoudness => _currentLoudness;
void Awake ( )
{
_microphoneName = Microphone.devices [ 0 ];
_microphoneClip = Microphone.Start ( _microphoneName, true, 20, AudioSettings.outputSampleRate );
if ( _microphoneClip != null )
_listening = true;
else
this.enabled = false;
}
void Update ( )
{
_currentLoudness = GetLoudnessFromAudioClip ( Microphone.GetPosition ( _microphoneName ), _microphoneClip, _sampleWindow );
if ( _currentLoudness < _lowThreshold )
BelowLowThreshold?.Invoke ( _currentLoudness );
else if ( _currentLoudness > _highThreshold )
AboveHighThreshold?.Invoke ( _currentLoudness );
}
public static float GetLoudnessFromAudioClip ( int clipPosition, AudioClip clip, int sampleWindow )
{
var startPosition = clipPosition - sampleWindow;
if ( startPosition < 0 ) return 0;
var waveData = new float[sampleWindow];
clip.GetData ( waveData, startPosition );
//compute loudness
var totalLoudness = 0f;
for ( var i = 0; i < sampleWindow; ++i )
totalLoudness += Mathf.Abs ( waveData [ i ] );
return totalLoudness / sampleWindow;
}
}
我首先添加了一些属性,最重要的是currentLoudness
。这是在每一帧期间计算的,因此不需要专门调用方法来计算它。您可以在 slider 或任何您想了解麦克风响度的其他地方读取此属性。有了这个属性,就不再需要 GetLoudnessFromMicrophone
。
还有值、低阈值和高阈值。这些用于确定事件是否被触发。这两个事件是 BelowLowThreshold
和 AboveHighThreshold
。
该代码假设麦克风在游戏过程中不会发生变化,并缓存到 Microphone.devices [ 0 ]
名称,以尝试减少垃圾产生。
最后,您可以像这样注册这些事件:
public class Test : MonoBehaviour
{
[SerializeField] private AudioLoudnessDetection _loudnessListener;
void Start ( )
{
if ( _loudnessListener != null && _loudnessListener.listening )
{
// Uncomment if you'd also like to know if the loudness goes below a threshold.
// _loudnessListener.BelowLowThreshold += OnBelowThreshold;
_loudnessListener.AboveHighThreshold += OnAboveThreshold;
}
}
private void OnAboveThreshold ( float loudness )
{
// loudness above threshold.
}
}
关于c# - 尝试创建一个系统,如果你的麦克风音量超过一定水平,Unity 中就会触发一个事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74073630/