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

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

  1. private int m_NumSamples = 256;
  2. private float[] m_Samples;
  3. private float sum, rms;
  4. private void Start()
  5. {
  6. audioSource = GetComponent<AudioSource>();
  7. BeginListener(0);
  8. //audioSource.clip = Microphone.Start(null, true, 10, 44100);
  9. m_Samples = new float[m_NumSamples];
  10. }
  11. private void Update()
  12. {
  13. audioSource.GetOutputData(m_Samples, 0);
  14. sum = m_Samples[m_NumSamples - 1] * m_Samples[m_NumSamples - 1];
  15. rms = Mathf.Sqrt(sum/* / m_NumSamples*/);
  16. float intensity = rms;
  17. Debug.Log(intensity);
  18. if (intensity > bootIntensity)
  19. {
  20. //change in shader
  21. material.SetFloat("_Intensity", intensity);
  22. }
  23. else
  24. {
  25. material.SetFloat("_Intensity", 0);
  26. }
  27. }

那么能不能用到粒子效果上呢,查了一下API果然不难做到。

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

我希望粒子随着音乐发射,音量越大数量越多,于是乎我们需要在脚本内通过检测音量来改变 Emission 模块的 Rate over Time 值(只是举个例子,当然有其他更漂亮的实现)

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

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

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

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

  1. private void Update()
  2. {
  3. var emission = m_ParticleSystem.emission;
  4. audioSource.GetOutputData(m_Samples, 0);
  5. sum = m_Samples[m_NumSamples - 1] * m_Samples[m_NumSamples - 1];
  6. rms = Mathf.Sqrt(sum/* / m_NumSamples*/);
  7. float intensity = rms;
  8. Debug.Log(intensity);
  9. if (intensity > bootIntensity)
  10. {
  11. emission.rateOverTime = 10f * (1 + intensity * 1000);
  12. }
  13. else
  14. {
  15. emission.rateOverTime = 10f;
  16. }
  17. }

Unity给的接口很方便,在脚本中开启Mic即可,具体代码如下:

  1. private void Start()
  2. {
  3. audioSource = GetComponent<AudioSource>();
  4. BeginListener(0);
  5. //audioSource.clip = Microphone.Start(null, true, 10, 44100);
  6. m_Samples = new float[m_NumSamples];
  7. }
  8. ......
  9. public void BeginListener(int index)
  10. {
  11. int min = 0;
  12. int max = 0;
  13. Microphone.GetDeviceCaps(Microphone.devices[index], out min, out max);
  14. audioSource.clip = Microphone.Start(Microphone.devices[index], true, 2, max);
  15. while (!(Microphone.GetPosition(Microphone.devices[index]) > 1))
  16. {
  17. // Wait until the recording has started
  18. }
  19. audioSource.loop = true;
  20. audioSource.Play();
  21. }

对着Mic吼的效果如下:

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

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

版权声明:本文为zhxmdefj原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/zhxmdefj/p/13261837.html