这有点棘手,但我会尝试解释我在做什么;)
基本上你想要做的是创建一个只包含两条线的新网格
所以我所做的是在开始时通过创建这两条线并将它们与三角面连接来创建网格。
然后稍后我只需将线渲染器的位置复制到新网格的顶行。
所以它可能看起来有点像
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoundVisualizer : MonoBehaviour
{
public LineRenderer line;
// Best already reference these via the Inspector
[SerializeField] private AudioSource _audioSource;
[SerializeField] private MeshFilter _meshFilter;
public int number = 64;
public float[] oldSpc;
public float range = 5000f;
public int spec;
[Range(0, 1)] public float speedAnimation;
// Stores the line positions
private Vector3[] positions;
// Stores the mesh reference
private Mesh _mesh;
private void Awake()
{
// As fallback get it ONCE on runtime
if (!_audioSource) _audioSource = GetComponent<AudioSource>();
if (!_meshFilter) _meshFilter = GetComponent<MeshFilter>();
_mesh = _meshFilter.mesh;
// Set the point amount via code
line.positionCount = number;
// Note that it is way more efficient to use GetPositions and SetPositions
// instead of using GetPosition and SetPosition multiple times!
positions = new Vector3[number];
line.GetPositions(positions);
for (var i = 0; i < number; i++)
{
positions[i] = Vector3.right * (0.2f* i);
}
line.SetPositions(positions);
if (spec < number) spec = number;
oldSpc = new float[spec];
// Now initialize the mesh once
// After having set up all the faces etc it is enough to only update
// The vertex positions
InitializeMesh();
}
private void Update()
{
var spectrum = new float[spec];
_audioSource.GetSpectrumData(spectrum, 0, FFTWindow.BlackmanHarris);
// Update the values inside of the array you already have
// -> no need to use GetPositions again
for (var i = 0; i < number; i++)
{
var position = positions[i];
positions[i] = Vector3.Lerp(position, new Vector3(position.x, (range * spectrum[i] + oldSpc[i]) / 2), speedAnimation);
oldSpc[i] = range * spectrum[i];
}
line.SetPositions(positions);
UpdateMesh();
}
private void InitializeMesh()
{
_mesh.Clear();
// Basically we will create a bottom and a top line each with "number" vertices
// Then later we create triangulated faces between these two lines
var vertices = new Vector3[number * 2];
for (var i = 0; i < number; i++)
{
vertices[i] = i * 0.2f * Vector3.right + Vector3.up * 1; // This will be the top line, for debugging set it to y = 1
vertices[i + number] = i * 0.2f * Vector3.right; // This will be the bottom line
}
var triangles = new int[2 * (number - 1) * 3]; // This is "number - 1" * amount f faces per segment (2) * vertices per face ( 3)
// Now lets create triangulated faces using these vertices and connecting the two lines
for (var i = 0; i < number - 1; i++)
{
triangles[6 * i] = i;
triangles[6 * i + 1] = i + 1;
triangles[6 * i + 2] = i + number;
triangles[6 * i + 3] = i + 1;
triangles[6 * i + 4] = i + number + 1;
triangles[6 * i + 5] = i + number;
}
_mesh.vertices = vertices;
_mesh.triangles = triangles;
_mesh.RecalculateNormals();
}
private void UpdateMesh()
{
// Basically we will simply update the positions of the top line in the mesh
// (= the first half of the vertices array)
// The rest (faces etc) will be updated automatically
var vertices = _mesh.vertices;
for (var i = 0; i < number; i++)
{
vertices[i] = positions[i];
}
_mesh.vertices = vertices;
}
}
所以只是为了展示它,我给这条线一个不同的颜色

所以最后要做的是调整厚度,或者换句话说,调整到底线的偏移量。我实际上会简单地降低底线
// In this line simply add some negative offset on Y
//
// |
// V
vertices[i + number] = i * 0.2f * Vector3.right - Vector3.up ; // This will be the bottom line
现在它看起来像这样:)

请注意,在当前版本中,您将无法在运行时调整 Inspector 的所有值;)
另请注意,LineRenderer 组件当然功能更强大,因为它还可以自动生成一些平滑的角落和东西