IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 学习笔记---Unity画线插件Vectrosity实现音频可视化的一个方法 -> 正文阅读

[游戏开发]学习笔记---Unity画线插件Vectrosity实现音频可视化的一个方法

实现的代码

    public AudioSource mAudio;
    /// <summary>
    /// 存放频谱数据的数组长度,长度必须为2的n次方,最小64,最大8192
    /// </summary>
    [Range(64, 128 * 2)]
    public int _sampleLength = 128 * 2;
    [Range(10, 50)]
    public float Frequency = 20;
    /// <summary>
    /// 音频频率数组
    /// </summary>
    public float[] samples;
    public Color lineColor = Color.green;
    //private VectorLine audioLine;
    private List<Vector3> linepoints;
    private VectorLine audioLine;
    public int pointCount;
    public GameObject cubePrefab;
    private Transform[] cubeTransform;//用来生成于频谱同等数量的预制体组
    Vector3 cubePos;//中间位置,用来对比cube位置于此帧的频谱数据
    private void Start()
	{
        Init();
    }
    private void Init()
    {
        GameObject tempCube;
        mAudio = GetComponent<AudioSource>();
        samples = new float[_sampleLength];
        pointCount = _sampleLength;
        linepoints = new List<Vector3>(pointCount);
        cubeTransform = new Transform[samples.Length];
        transform.position = new Vector3(-samples.Length * 0.5f, transform.position.y, transform.position.z);
        print("画线初始化开始");
        audioLine = new VectorLine("audioline", linepoints, 5.0f, LineType.Continuous);
        //根据获取的音频长度生成预制体组,并初始化Cube的位置
        for (int i = 0; i < samples.Length; i++)
        {
            tempCube = Instantiate(cubePrefab, new Vector3(transform.position.x + i, transform.position.y, transform.position.z), Quaternion.identity);
            cubeTransform[i] = tempCube.transform;
            cubeTransform[i].parent = transform;
        }
        audioLine.color = lineColor;
        //audioLine.Draw();
        print("画线结束");
        //audioLine.drawTransform = transform;
    }
    private void Update()
	{
        //GetAudioData();
    }
    private void LateUpdate()
    {
        GetAudioData();
    }
    /// <summary>
    /// 根据获取音频频谱更新cube的位置及画线让频谱可视化
    /// </summary>
    private void GetAudioData()
    {
        //获取频谱
        mAudio.GetSpectrumData(samples, 0, FFTWindow.BlackmanHarris);
        for (int i = 0; i < samples.Length; i++)
        {
            //linepoints[i]=new Vector3(i, Mathf.Clamp(samples[i] * (50 + i * i * 0.5f), 0, 50), 1);
            //print(linepoints[i]);
            //设置每一个cube的位置
            var Pos = new Vector3(cubeTransform[i].position.x, Mathf.Clamp(samples[i] * (50 + i * i * 0.5f), 0, 100), cubeTransform[i].position.z);
            cubePos = Pos;
            //cubePos.Set(ScreenPos);//频谱的数据主要是用来设置cube的y值,使用Mathf.Clamp将y值限制在一定范围,避免过大
            //频谱值越向后越小,为避免后面的数据变化不明显,所以在扩大sample[i]时,乘以50+i*i*0.5f
            linepoints[i] = cubePos - Vector3.up;//控制线点的位置始终位于预制体下面
            if (cubeTransform[i].position.y < cubePos.y)
            {
                //当频谱位置大于当前预制体位置,则设为频谱位置
                cubeTransform[i].position = cubePos;
            }
            else if (cubeTransform[i].position.y > cubePos.y)
            {
                //当频谱位置小于当前预制体位置,则当前位置y值每次减少0.5,形成下落的效果
                cubeTransform[i].position -= new Vector3(0, 0.5f, 0);
            }
        }
        audioLine.Draw();
        if (Event.current.type == EventType.KeyDown || Event.current.type == EventType.KeyUp) return;
    }

插件和demo下载地址:
Unity5.4以上的版本都支持的Vectrosity插件
音频可视化源工程
实现的一个效果:
在这里插入图片描述

Vectrosity插件的介绍

在Unity中使用这款插件可以绘制2d/3d/贝塞尔/圆/椭圆等线条图案。
使用步骤:
1.导入插件包,引入命名空间using Vectrosity
2.声明一个画线对象VectorLine line
3.在开始方法里实例化VectorLine对象:
在这里插入图片描述
4.设置位置坐标点到链表里去
5.调用line.Drwa()方法即可绘制所需线条图案
在这里插入图片描述

这是VectorLine类里的构造函数
其中name表示生成的线段的名字,points表示可以存放Vector2和Vector3类型的数据,用于在屏幕上绘制点,width表示生成线的宽度的像素值,texture表示线的材质,设为null表示默认材质,LineType有三个枚举是用来设置线条的类型的,Joins也有三个枚举是用来设置两条线段之间的过渡方式的。
在这里插入图片描述
在这里插入图片描述
其中continuous表示连续的,discrete表示离散的,points表示点的
Fill表示填充的,weld表示连接的,none表示没有连接的
在这里插入图片描述
编辑器运行时点击渲染组件会报错报错:
在这里插入图片描述
1、InvalidOperationException: This cannot be used during play mode.
2、ArgumentException: Getting control 7’s position in a group with only 7 controls when doing Repaint
3、ArgumentException: Getting control 7’s position in a group with only 7 controls when doing ScrollWheel

暂时没找到解放方法,还请大佬指点,记录在这以后研究一下。

Unity音频可视化的一个方法

利用音频的频谱率转化成线图的方式展现音频的波动效果。
简单实现:
1、Unity提供了AudioListener.GetSpectrumData可以直接获取音频的频谱。
语法:public void GetSpectrumData(float[] samples,int channel,FFTWindow window);
samples:
函数返回值。每个元素代表该音源当前在某个赫兹的强度。针对快速傅里叶变换算法的性能,数组大小必须为2的n次方,最小64,最大8192。
channel:
一般设置为0。该参数与硬件是mono或是stereo有关,mono的话所有的音响会播放同一个音源,而stereo立体声的话不同的音响会播放不同的音源,因此出现了一个channel的概念,通过指定channel可以只取stereo的某个音源的data,设为0的话会按照mono的方式取整个音源。
window:
辅助快速傅里叶变换的窗函数,算法越复杂,声音越柔和,但速度更慢。
2、然后根据这些频谱数据的值来生成cube,根据cube的位置参数生成点,再利用Vecttosity插件画线,就可以实现一个简单音频可视化效果了。
3、关于Mathf.Clamp:
语法:public static float Clamp(float value,float min,float max);
在这里插入图片描述
这个函数可以返回一个最小值到最大值之间的浮点值结果。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-09-07 11:09:07  更:2021-09-07 11:09:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/21 19:57:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码