学习笔记---Unity画线插件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);
在这里插入图片描述
这个函数可以返回一个最小值到最大值之间的浮点值结果。

实现的代码***

    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插件
音频可视化源工程

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Vectorsity是一款在Unity游戏引擎中使用的画线插件。它通过提供简单易用的API,使开发者能够方便地在3D场景中绘制直线、曲线等几何形状。Vectorsity具有许多强大的功能和特点。 首先,Vectorsity提供了丰富的画线选项。开发者可以定义线段的起点和终点,设置线段的颜色、宽度以及透明度。此外,还可以调整线段的端点样式,如箭头、圆形等,以及线段的虚线样式。 其次,Vectorsity支持绘制曲线。开发者可以通过指定控制点来创建贝塞尔曲线,还可以设置曲线的分段数和平滑度。此外,可以通过添加锚点来使曲线在不同的地方有不同的弯曲程度。 另外,Vectorsity还提供了多种画线方法。开发者可以绘制直线、折线、曲线等各种几何形状。此外,还可以在已有的线段上继续绘制,使得绘制复杂的路径变得更加便捷。 除此之外,Vectorsity还支持画线的交互性。开发者可以通过监听鼠标点击或触摸事件,在用户交互的情况下动态绘制线段。这在制作绘画类游戏或实现交互式的路径规划系统时非常有用。 总之,Vectorsity是一款功能强大、易于使用的Unity画线插件。它提供了丰富的画线选项,支持绘制直线、曲线等各种几何形状,并且还可以实现交互性。无论是制作游戏还是开发其他类型的应用程序,Vectorsity都是一款极具价值的工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周周的Unity小屋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值