• Unity音量可视化——粒子随声浪跳动


    本文涉及的源码包含在安卓Unity渲染互通的 Demo 里,直接打开 Unity 工程的 Test 场景就行,不用管安卓工程。

    脚本控制粒子

    起初是看到这么一篇博客 Shader特效—— 音符跳动,效果如下图:

    具体的shader代码就不贴在这里了,他的博客里都有。
    处理音频的关键代码如下(修改过):

    private int m_NumSamples = 256;
    private float[] m_Samples;
    private float sum, rms;
    
    private void Start()
    {
        audioSource = GetComponent<AudioSource>();
        audioSource.clip = Microphone.Start(null, true, 10, 44100);
        m_Samples = new float[m_NumSamples];
    }
    
    private void Update()
    {
        audioSource.GetOutputData(m_Samples, 0);
        sum = m_Samples[m_NumSamples - 1] * m_Samples[m_NumSamples - 1];
        rms = Mathf.Sqrt(sum/* / m_NumSamples*/);
        float intensity = rms;
        Debug.Log(intensity);
        if (intensity > bootIntensity)
        {
            //change in shader
            material.SetFloat("_Intensity", intensity);
        }
        else
        {
            material.SetFloat("_Intensity", 0);
        }
    }
    

    只要目前的 intensity 超过了预设的 bootIntensity ,就允许 shader 做出反应,实现上图小球抖动的效果。那么能不能套用到粒子效果上呢,查了一下API果然不难做到。

    这里用一个球状发射的粒子模块来做示例:

    我希望粒子随着音乐发射,音量越大数量越多,于是乎我们需要在脚本内通过检测音量来改变 Emission 模块的 Rate over Time 值,当然这里只是举个例子,还有更漂亮的实现。至于 Bursts 值可有可无,只是一个点缀。(当然 Burst 也可通过脚本控制)

    一开始我盲写,果然有 rateOverTime 这个值,但是不允许我直接更改。

    查了下 API-ParticleSystem.EmissionModule 后发现不能直接用脚本赋值,而是需要实例化之后赋值:

    var emission = m_ParticleSystem.emission;
    emission.rateOverTime = 100f;
    

    那么事情就好办了,复用上面的脚本代码就可以控制粒子了:

    private void Update()
    {
        var emission = m_ParticleSystem.emission;
        audioSource.GetOutputData(m_Samples, 0);
        sum = m_Samples[m_NumSamples - 1] * m_Samples[m_NumSamples - 1];
        rms = Mathf.Sqrt(sum/* / m_NumSamples*/);
        float intensity = rms;
        Debug.Log(intensity);
        if (intensity > bootIntensity)
        {
            emission.rateOverTime = 10f * (1 + intensity * 1000);
        }
        else
        {
            emission.rateOverTime = 10f;
        }
    }
    

    别忘了给他加上一个 AudioSource 组件,将音频文件拖入 AudioClip 即可

    接入Mic

    Unity给的接口很方便,基本不用怎么改,首先把上面 AudioClip 的音源文件清了,我们会在脚本中获取麦克风输入信息作为音源,具体代码如下:

    private void Start()
    {
        audioSource = GetComponent<AudioSource>();
        BeginListener(0);
        //audioSource.clip = Microphone.Start(null, true, 10, 44100);
        m_Samples = new float[m_NumSamples];
    }
    
    ......
    
    public void BeginListener(int index)
    {
        int min = 0;
        int max = 0;
    
        Microphone.GetDeviceCaps(Microphone.devices[index], out min, out max);
    
        audioSource.clip = Microphone.Start(Microphone.devices[index], true, 2, max);
    
        while (!(Microphone.GetPosition(Microphone.devices[index]) > 1))
        {
            // Wait until the recording has started
        }
    
        audioSource.loop = true;
        audioSource.Play();
    }
    

    运行,对着Mic吼的效果如下:

    不建议在办公室吼,吹气也可以达到这样的效果。。。

    本人不太熟悉粒子系统,有兴趣的朋友可以自己实现更多更酷的特效,感谢阅读

  • 相关阅读:
    面试题目1:spring和springmvc的区别与联系
    Vue---第二十三章v-on事件处理
    Vue---第二十二章v-for循环
    Vue-接口返回的值在页面上显示
    Vue---第二十一章v-if
    Vue---第二十章class和style,v-bind
    Vue---第十九章计算属性和监听器
    Vue---第十八章元素绑定v-bind,v-on
    Vue---第十七章v-once
    Vue---第十六章devtools
  • 原文地址:https://www.cnblogs.com/zhxmdefj/p/13261837.html
Copyright © 2020-2023  润新知