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吼的效果如下:
不建议在办公室吼,吹气也可以达到这样的效果。。。
本人不太熟悉粒子系统,有兴趣的朋友可以自己实现更多更酷的特效,感谢阅读
分类:
Unity
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
2019-07-07 二维费用,依赖,分组背包