c# - 尝试创建一个系统,如果你的麦克风音量超过一定水平,Unity 中就会触发一个事件

标签 c# unity-game-engine

所以我目前正在 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

还有值、低阈值和高阈值。这些用于确定事件是否被触发。这两个事件是 BelowLowThresholdAboveHighThreshold

该代码假设麦克风在游戏过程中不会发生变化,并缓存到 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/

相关文章:

c# - 删除唯一约束并使用户名在 ASP.NET Identity 中可为空

facebook - Unity Facebook SDK 发布操作

android - Unity3d 应用内购买的免费 Android 插件

c# - 如何使用 ASP.NET MVC 中的路由修复 404?

c# - 触发器返回一个结果集和/或在 SET NOCOUNT OFF 的情况下运行,而另一个未完成的结果集处于事件状态

c# - .NET Core 2.0 分离 Startup.cs 服务注入(inject)

c# - 捕获委托(delegate)的所有返回值

firebase - 在 Android 上统一构建 crashlytics 时遇到麻烦

c# - UnityARAlignment 在 Unity ARKit 插件中意味着什么?

unity-game-engine - 我可以更改 iOS 启动屏幕,但无法更改 Android 启动屏幕。为什么?