You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中基于单位圆的动态可调振幅频率正弦波生成咨询

Unity 基于单位圆的动态正弦波生成器实现方案

嘿,我来帮你搞定这个基于单位圆的动态正弦波生成器!刚好这个需求的本质就是利用正弦函数的几何意义——单位圆上点的y轴投影,咱们一步步实现,还能实时调整参数看直观效果:

1. 先搭好场景元素

首先得把可视化的东西准备好,让你能看到单位圆和正弦波的关联:

  • 单位圆:用Sprite(找个圆形图)或者LineRenderer画一个圆,命名为UnitCircle,放在屏幕左侧方便观察。
  • 圆上标记点:弄个小Sphere或者UI Image(比如小方块),命名为CirclePoint,作为单位圆上的动态投影点。
  • 正弦波绘制器:添加一个LineRenderer组件的空物体,命名为SineWaveRenderer,用来画生成的波形。
  • 参数控制器(可选但推荐):加两个Slider UI控件,分别用来调振幅(单位圆半径)和频率(旋转速度),不用改代码就能实时调效果。

2. 核心脚本实现

创建一个名为SineWaveGenerator的脚本,挂载到一个空物体(比如WaveController)上,代码如下,我会给你标清楚关键逻辑:

using UnityEngine;
using UnityEngine.UI;

public class SineWaveGenerator : MonoBehaviour
{
    [Header("单位圆相关")]
    public Transform unitCircle;
    public Transform circlePoint;
    public float amplitude = 1f; // 振幅直接对应单位圆半径
    public float frequency = 1f; // 频率对应单位圆点的旋转速度(弧度/秒)

    [Header("正弦波绘制")]
    public LineRenderer waveRenderer;
    public int wavePointCount = 100; // 波形的点数,越多越平滑
    public float waveLength = 10f; // 屏幕上显示的波形长度

    [Header("UI控制")]
    public Slider amplitudeSlider;
    public Slider frequencySlider;

    private Vector3[] wavePoints;
    private float timeElapsed;

    void Start()
    {
        // 初始化LineRenderer的点数组
        wavePoints = new Vector3[wavePointCount];
        waveRenderer.positionCount = wavePointCount;

        // 绑定Slider的回调,实现实时调参
        if (amplitudeSlider != null)
        {
            amplitudeSlider.value = amplitude;
            amplitudeSlider.onValueChanged.AddListener(UpdateAmplitude);
        }
        if (frequencySlider != null)
        {
            frequencySlider.value = frequency;
            frequencySlider.onValueChanged.AddListener(UpdateFrequency);
        }
    }

    void Update()
    {
        // 累计时间,驱动整个动画
        timeElapsed += Time.deltaTime;

        // 计算单位圆点的极坐标位置:旋转角度由时间和频率决定
        float angle = timeElapsed * frequency * Mathf.PI * 2; // *2PI让频率1对应每秒转一圈
        float circleX = Mathf.Cos(angle) * amplitude;
        float circleY = Mathf.Sin(angle) * amplitude;
        circlePoint.localPosition = new Vector3(circleX, circleY, 0);

        // 同步单位圆的缩放:振幅就是半径,直接改scale就行
        unitCircle.localScale = new Vector3(amplitude, amplitude, 1);

        // 生成正弦波的每个点,实现滚动效果
        for (int i = 0; i < wavePointCount; i++)
        {
            // 给每个点加时间偏移,让波形从左到右是“历史”的投影
            float timeOffset = (float)i / wavePointCount * waveLength;
            float waveY = Mathf.Sin((timeElapsed - timeOffset) * frequency * Mathf.PI * 2) * amplitude;
            wavePoints[i] = new Vector3((float)i / wavePointCount * waveLength, waveY, 0);
        }

        // 把点传给LineRenderer绘制波形
        waveRenderer.SetPositions(wavePoints);
    }

    // 振幅实时更新函数
    public void UpdateAmplitude(float value)
    {
        amplitude = value;
    }

    // 频率实时更新函数
    public void UpdateFrequency(float value)
    {
        frequency = value;
    }
}

关键逻辑解释

  • 单位圆与投影点:通过极坐标计算CirclePoint的位置,频率越高,点转得越快;振幅就是单位圆的半径,所以直接缩放UnitCircle的transform来可视化。
  • 滚动正弦波:给LineRenderer的每个点加时间偏移,这样随着时间推移,波形会从右向左滚动(或者反过来,你可以改符号调整方向),完美还原连续的正弦曲线。
  • 动态调参:Slider的回调函数会实时修改amplitude和frequency,不用重启游戏,拖动滑块就能看到单位圆和正弦波同步变化。

3. 场景配置小技巧

  • 把UnitCircle放在屏幕左侧,SineWaveRenderer放在右侧,这样能直观看到圆上点的y值和波形的对应关系。
  • 调大LineRenderer的宽度(比如0.1),用纯色材质,让波形更清晰。
  • 把CirclePoint的尺寸调小一点,比如Sphere的Scale设为(0.2,0.2,0.2),方便看清它在圆上的位置。
  • 如果用UI元素,记得把所有物体放在Canvas下,调整RectTransform的位置适配屏幕。

4. 效果验证

运行游戏后,拖动振幅滑块,单位圆的半径会跟着变大/变小,正弦波的高低也同步变化;拖动频率滑块,圆上的点旋转速度变快/变慢,正弦波的密集程度也会对应改变,完全符合你要的直观展示效果。

内容的提问来源于stack exchange,提问作者Pratham Sehgal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:28:59