776 lines
28 KiB
C#
776 lines
28 KiB
C#
using UnityEngine;
|
|
|
|
namespace AibisDream.MiniGame.HuoShan
|
|
{
|
|
/// <summary>
|
|
/// 波形渲染器 - 单个波形的渲染
|
|
/// 支持噪波效果和清晰度控制,像录音软件中的声波
|
|
/// </summary>
|
|
[ExecuteInEditMode]
|
|
[RequireComponent(typeof(LineRenderer))]
|
|
public class WaveformRenderer : MonoBehaviour
|
|
{
|
|
public enum PreviewMode
|
|
{
|
|
Clean, // 清晰波形,无噪波
|
|
WithNoise, // 显示噪波效果
|
|
Runtime // 模拟运行时(噪波+清晰度)
|
|
}
|
|
|
|
public enum ConfigPreviewType
|
|
{
|
|
None, // 不使用Config,使用下方的手动设置
|
|
Emotion, // 预览情绪波形配置
|
|
Logic, // 预览逻辑波形配置
|
|
Joke, // 预览笑话波形配置
|
|
FilterOutput, // 预览滤波器输出配置
|
|
NormalOutput // 预览正常输出配置
|
|
}
|
|
|
|
[Header("═══ 从Config预览(拖入Config后选择类型即可预览)═══")]
|
|
[Tooltip("拖入WaveformConfig资源")]
|
|
[SerializeField] private WaveformConfig previewConfig;
|
|
[Tooltip("选择要预览的波形类型(选择后立即生效)")]
|
|
[SerializeField] private ConfigPreviewType previewFromConfig = ConfigPreviewType.None;
|
|
|
|
[Header("═══ 预览效果 ═══")]
|
|
[SerializeField] private PreviewMode editorPreviewMode = PreviewMode.Clean;
|
|
[Tooltip("勾选强制刷新波形显示")]
|
|
[SerializeField] private bool forceRefresh = false;
|
|
|
|
[Header("═══ 波形设置(手动调整或从Config应用)═══")]
|
|
[SerializeField] private WaveformType waveType = WaveformType.Emotion;
|
|
[SerializeField] private float waveHeight = 1f;
|
|
[SerializeField] private float waveWidth = 10f;
|
|
[SerializeField] private float waveSpeed = 2f;
|
|
[SerializeField] private float frequency = 1f;
|
|
|
|
[Header("噪波设置")]
|
|
[SerializeField] private float noiseAmount = 0.8f; // 噪波强度 (0=无噪波, 1=完全噪波)
|
|
[SerializeField] private float noiseFrequency = 15f; // 噪波频率
|
|
[SerializeField] private float noiseSpeed = 5f; // 噪波变化速度
|
|
|
|
[Header("清晰度设置")]
|
|
[SerializeField] private float clarity = 0f; // 清晰度 (0=模糊, 1=完全清晰)
|
|
[SerializeField] private float clarityPosition = 0.5f; // 清晰位置 (0-1)
|
|
[SerializeField] private float clarityWidth = 0.1f; // 清晰区域宽度
|
|
|
|
[Header("绘图设置")]
|
|
[SerializeField] private int resolution = 200;
|
|
[SerializeField] private float lineWidth = 0.05f;
|
|
|
|
[Header("颜色设置")]
|
|
[SerializeField] private Color primaryColor = Color.cyan;
|
|
[SerializeField] private Color secondaryColor = Color.blue;
|
|
[SerializeField] private Color noiseColor = new Color(0.5f, 0.5f, 0.5f, 0.5f);
|
|
[SerializeField] private Color clearColor = Color.green;
|
|
|
|
[Header("发光点")]
|
|
[SerializeField] private bool showGlowPoint = true;
|
|
[SerializeField] private SpriteRenderer glowPointRenderer;
|
|
[SerializeField] private float glowSize = 0.15f;
|
|
|
|
private LineRenderer _lineRenderer;
|
|
private Vector3[] _points;
|
|
private float _phaseOffset = 0f;
|
|
private float _noisePhase = 0f;
|
|
private float _transformProgress = 0f;
|
|
private WaveformType _transformFromType;
|
|
private WaveformType _transformToType;
|
|
private bool _isTransforming = false;
|
|
private float _currentAlpha = 1f;
|
|
|
|
// 随机噪波种子
|
|
private float[] _noiseSeed;
|
|
|
|
// 合成模式参数
|
|
private float _logicWeight = 0.3f;
|
|
private float _jokeWeight = 0.85f;
|
|
private float _synthesisProgress = 1f;
|
|
|
|
public WaveformType WaveType => waveType;
|
|
public bool IsTransforming => _isTransforming;
|
|
public float Clarity => clarity;
|
|
public float ClarityPosition => clarityPosition;
|
|
public float ClarityWidth => clarityWidth;
|
|
public float NoiseAmount => noiseAmount;
|
|
public Color PrimaryColor => primaryColor;
|
|
public Color SecondaryColor => secondaryColor;
|
|
public float CurrentAlpha => _currentAlpha;
|
|
|
|
private void Awake()
|
|
{
|
|
InitializeLineRenderer();
|
|
SetupGlowPoint();
|
|
InitializeNoise();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 响应 Inspector 中的值变化
|
|
/// </summary>
|
|
private void OnValidate()
|
|
{
|
|
// 确保在编辑器中能即时预览
|
|
if (_lineRenderer == null)
|
|
{
|
|
_lineRenderer = GetComponent<LineRenderer>();
|
|
}
|
|
|
|
if (_lineRenderer != null)
|
|
{
|
|
_lineRenderer.startWidth = lineWidth;
|
|
_lineRenderer.endWidth = lineWidth;
|
|
|
|
if (_points == null || _points.Length != resolution)
|
|
{
|
|
_points = new Vector3[resolution];
|
|
_lineRenderer.positionCount = resolution;
|
|
}
|
|
|
|
UpdateColors();
|
|
}
|
|
|
|
// 检查Config预览设置
|
|
if (previewFromConfig != ConfigPreviewType.None && previewConfig == null)
|
|
{
|
|
Debug.LogWarning("WaveformRenderer: 请先拖入 WaveformConfig 资源到 Preview Config 字段!");
|
|
}
|
|
|
|
// 强制刷新按钮
|
|
if (forceRefresh)
|
|
{
|
|
forceRefresh = false;
|
|
InitializeNoise();
|
|
|
|
// 显示实际使用的参数
|
|
if (previewFromConfig != ConfigPreviewType.None && previewConfig != null)
|
|
{
|
|
var settings = GetPreviewSettings();
|
|
if (settings != null)
|
|
{
|
|
Debug.Log($"WaveformRenderer: 预览Config [{previewFromConfig}] - 类型:{settings.waveType}, 高度:{settings.waveHeight}, 速度:{settings.waveSpeed}, 频率:{settings.frequency}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.Log($"WaveformRenderer: 使用本地参数 - 类型:{waveType}, 高度:{waveHeight}, 速度:{waveSpeed}, 频率:{frequency}");
|
|
}
|
|
}
|
|
|
|
if (_noiseSeed == null || _noiseSeed.Length != resolution)
|
|
{
|
|
InitializeNoise();
|
|
}
|
|
|
|
// 在编辑器中立即更新波形
|
|
if (!Application.isPlaying)
|
|
{
|
|
UpdateWaveform();
|
|
}
|
|
}
|
|
|
|
|
|
private void InitializeLineRenderer()
|
|
{
|
|
_lineRenderer = GetComponent<LineRenderer>();
|
|
if (_lineRenderer == null) return;
|
|
|
|
_lineRenderer.useWorldSpace = false;
|
|
_lineRenderer.positionCount = resolution;
|
|
_lineRenderer.startWidth = lineWidth;
|
|
_lineRenderer.endWidth = lineWidth;
|
|
|
|
_points = new Vector3[resolution];
|
|
|
|
UpdateColors();
|
|
}
|
|
|
|
private void InitializeNoise()
|
|
{
|
|
_noiseSeed = new float[resolution];
|
|
for (int i = 0; i < resolution; i++)
|
|
{
|
|
_noiseSeed[i] = Random.Range(0f, 100f);
|
|
}
|
|
}
|
|
|
|
private void SetupGlowPoint()
|
|
{
|
|
if (!showGlowPoint) return;
|
|
|
|
if (glowPointRenderer == null)
|
|
{
|
|
GameObject glowObj = new GameObject("GlowPoint");
|
|
glowObj.transform.SetParent(transform);
|
|
glowObj.transform.localPosition = Vector3.zero;
|
|
glowPointRenderer = glowObj.AddComponent<SpriteRenderer>();
|
|
|
|
Texture2D texture = new Texture2D(32, 32);
|
|
Color[] colors = new Color[32 * 32];
|
|
for (int i = 0; i < colors.Length; i++)
|
|
{
|
|
float x = (i % 32) / 31f;
|
|
float y = (i / 32) / 31f;
|
|
float distance = Vector2.Distance(new Vector2(x, y), new Vector2(0.5f, 0.5f));
|
|
colors[i] = new Color(1, 1, 1, Mathf.Clamp01(1 - distance * 2));
|
|
}
|
|
texture.SetPixels(colors);
|
|
texture.Apply();
|
|
|
|
Sprite sprite = Sprite.Create(texture, new Rect(0, 0, 32, 32), new Vector2(0.5f, 0.5f));
|
|
glowPointRenderer.sprite = sprite;
|
|
}
|
|
|
|
glowPointRenderer.color = primaryColor;
|
|
glowPointRenderer.transform.localScale = Vector3.one * glowSize;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (_lineRenderer == null) InitializeLineRenderer();
|
|
if (_points == null) _points = new Vector3[resolution];
|
|
if (_noiseSeed == null) InitializeNoise();
|
|
|
|
// 获取实际波形速度(优先使用Config预览)
|
|
float actualWaveSpeed = waveSpeed;
|
|
bool isEditor = !Application.isPlaying;
|
|
if (isEditor && previewFromConfig != ConfigPreviewType.None && previewConfig != null)
|
|
{
|
|
WaveformSettings settings = GetPreviewSettings();
|
|
if (settings != null)
|
|
{
|
|
actualWaveSpeed = settings.waveSpeed;
|
|
}
|
|
}
|
|
|
|
_phaseOffset += Time.deltaTime * actualWaveSpeed;
|
|
_noisePhase += Time.deltaTime * noiseSpeed;
|
|
UpdateWaveform();
|
|
}
|
|
|
|
private void UpdateWaveform()
|
|
{
|
|
if (_lineRenderer == null || _points == null) return;
|
|
|
|
// 确定当前使用的预览模式
|
|
bool isEditor = !Application.isPlaying;
|
|
PreviewMode currentMode = isEditor ? editorPreviewMode : PreviewMode.Runtime;
|
|
|
|
// 获取实际使用的参数(优先使用Config预览)
|
|
WaveformType actualWaveType = waveType;
|
|
float actualFrequency = frequency;
|
|
float actualWaveHeight = waveHeight;
|
|
float actualWaveSpeed = waveSpeed;
|
|
|
|
if (isEditor && previewFromConfig != ConfigPreviewType.None && previewConfig != null)
|
|
{
|
|
WaveformSettings settings = GetPreviewSettings();
|
|
if (settings != null)
|
|
{
|
|
actualWaveType = settings.waveType;
|
|
actualFrequency = settings.frequency;
|
|
actualWaveHeight = settings.waveHeight;
|
|
actualWaveSpeed = settings.waveSpeed;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < resolution; i++)
|
|
{
|
|
float x = ((float)i / resolution) * waveWidth - waveWidth * 0.5f;
|
|
float normalizedX = (float)i / resolution;
|
|
float timeOffset = normalizedX * actualFrequency + _phaseOffset;
|
|
|
|
// 获取基础波形值
|
|
float baseWaveValue;
|
|
if (_isTransforming)
|
|
{
|
|
float fromValue = GetWaveValue(_transformFromType, timeOffset, normalizedX);
|
|
float toValue = GetWaveValue(_transformToType, timeOffset, normalizedX);
|
|
baseWaveValue = Mathf.Lerp(fromValue, toValue, _transformProgress);
|
|
}
|
|
else
|
|
{
|
|
baseWaveValue = GetWaveValue(actualWaveType, timeOffset, normalizedX);
|
|
}
|
|
|
|
float finalValue;
|
|
switch (currentMode)
|
|
{
|
|
case PreviewMode.Clean:
|
|
// 清晰模式:直接显示波形
|
|
finalValue = baseWaveValue;
|
|
break;
|
|
|
|
case PreviewMode.WithNoise:
|
|
// 噪波模式:只显示噪波效果,不考虑清晰度
|
|
float noise = GenerateNoise(i, normalizedX);
|
|
finalValue = Mathf.Lerp(noise, baseWaveValue, 1f - noiseAmount);
|
|
break;
|
|
|
|
case PreviewMode.Runtime:
|
|
default:
|
|
// 运行时模式:应用噪波和清晰度
|
|
float localClarity = CalculateLocalClarity(normalizedX);
|
|
float runtimeNoise = GenerateNoise(i, normalizedX);
|
|
finalValue = Mathf.Lerp(runtimeNoise, baseWaveValue, localClarity);
|
|
break;
|
|
}
|
|
|
|
_points[i] = new Vector3(x, finalValue * actualWaveHeight, 0f);
|
|
}
|
|
|
|
_lineRenderer.SetPositions(_points);
|
|
UpdateLineColors();
|
|
|
|
if (showGlowPoint && glowPointRenderer != null && resolution > 0)
|
|
{
|
|
glowPointRenderer.transform.localPosition = _points[resolution - 1];
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取当前预览的Config设置
|
|
/// </summary>
|
|
private WaveformSettings GetPreviewSettings()
|
|
{
|
|
if (previewConfig == null) return null;
|
|
|
|
switch (previewFromConfig)
|
|
{
|
|
case ConfigPreviewType.Emotion:
|
|
return previewConfig.emotionWaveform;
|
|
case ConfigPreviewType.Logic:
|
|
return previewConfig.logicWaveform;
|
|
case ConfigPreviewType.Joke:
|
|
return previewConfig.jokeWaveform;
|
|
case ConfigPreviewType.FilterOutput:
|
|
return previewConfig.filterOutputWaveform;
|
|
case ConfigPreviewType.NormalOutput:
|
|
return previewConfig.normalOutputWaveform;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算指定位置的局部清晰度
|
|
/// </summary>
|
|
private float CalculateLocalClarity(float normalizedX)
|
|
{
|
|
// 基础清晰度
|
|
float baseClarity = clarity;
|
|
|
|
// 如果清晰度大于0,在清晰位置附近更清晰
|
|
if (clarity > 0)
|
|
{
|
|
float distanceFromClear = Mathf.Abs(normalizedX - clarityPosition);
|
|
float clearZone = 1f - Mathf.Clamp01(distanceFromClear / clarityWidth);
|
|
baseClarity = Mathf.Max(clarity, clearZone);
|
|
}
|
|
|
|
return Mathf.Clamp01(baseClarity);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生成噪波(像录音软件中的声波)
|
|
/// </summary>
|
|
private float GenerateNoise(int index, float normalizedX)
|
|
{
|
|
float seed = _noiseSeed[index];
|
|
|
|
// 多层噪波叠加,产生声波效果
|
|
float noise = 0f;
|
|
|
|
// 低频噪波 - 整体起伏
|
|
noise += Mathf.PerlinNoise(seed + _noisePhase * 0.3f, normalizedX * 2f) * 0.6f;
|
|
|
|
// 中频噪波 - 细节
|
|
noise += Mathf.PerlinNoise(seed * 2f + _noisePhase * 0.7f, normalizedX * 5f) * 0.3f;
|
|
|
|
// 高频噪波 - 毛刺
|
|
noise += (Mathf.PerlinNoise(seed * 3f + _noisePhase, normalizedX * noiseFrequency) - 0.5f) * 0.4f;
|
|
|
|
// 随机尖峰(像声波的峰值)
|
|
float spike = Mathf.Sin((normalizedX + _noisePhase * 0.1f) * Mathf.PI * 20f);
|
|
spike = Mathf.Pow(Mathf.Abs(spike), 3f) * Mathf.Sign(spike);
|
|
noise += spike * 0.2f;
|
|
|
|
// 归一化到 -1 到 1
|
|
noise = (noise - 0.5f) * 2f * noiseAmount;
|
|
|
|
return Mathf.Clamp(noise, -1f, 1f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新线条颜色(清晰区域显示不同颜色)
|
|
/// </summary>
|
|
private void UpdateLineColors()
|
|
{
|
|
if (_lineRenderer == null) return;
|
|
|
|
Gradient gradient = new Gradient();
|
|
|
|
if (clarity > 0.5f)
|
|
{
|
|
// 有清晰区域时,显示清晰位置的颜色变化
|
|
float clearStart = Mathf.Clamp01(clarityPosition - clarityWidth);
|
|
float clearEnd = Mathf.Clamp01(clarityPosition + clarityWidth);
|
|
|
|
gradient.SetKeys(
|
|
new GradientColorKey[] {
|
|
new GradientColorKey(primaryColor, 0f),
|
|
new GradientColorKey(primaryColor, clearStart),
|
|
new GradientColorKey(clearColor, clarityPosition),
|
|
new GradientColorKey(primaryColor, clearEnd),
|
|
new GradientColorKey(secondaryColor, 1f)
|
|
},
|
|
new GradientAlphaKey[] {
|
|
new GradientAlphaKey(_currentAlpha, 0f),
|
|
new GradientAlphaKey(_currentAlpha, 1f)
|
|
}
|
|
);
|
|
}
|
|
else
|
|
{
|
|
gradient.SetKeys(
|
|
new GradientColorKey[] {
|
|
new GradientColorKey(primaryColor, 0f),
|
|
new GradientColorKey(secondaryColor, 1f)
|
|
},
|
|
new GradientAlphaKey[] {
|
|
new GradientAlphaKey(_currentAlpha, 0f),
|
|
new GradientAlphaKey(_currentAlpha, 1f)
|
|
}
|
|
);
|
|
}
|
|
|
|
_lineRenderer.colorGradient = gradient;
|
|
}
|
|
|
|
private float GetWaveValue(WaveformType type, float time, float normalizedX)
|
|
{
|
|
switch (type)
|
|
{
|
|
case WaveformType.Emotion:
|
|
return GenerateEmotionWave(time, normalizedX);
|
|
case WaveformType.Logic:
|
|
return GenerateLogicWave(time);
|
|
case WaveformType.Joke:
|
|
return GenerateJokeWave(time, normalizedX);
|
|
case WaveformType.FilterOutput:
|
|
return GenerateFilterOutput(time, normalizedX);
|
|
case WaveformType.NormalOutput:
|
|
return GenerateNormalOutput(time, normalizedX);
|
|
default:
|
|
return Mathf.Sin(time * Mathf.PI * 2f);
|
|
}
|
|
}
|
|
|
|
#region 波形生成
|
|
|
|
/// <summary>
|
|
/// 情绪波形 - 低沉、缓慢、压抑、忧伤
|
|
/// 特征:非常低的频率,缓慢的起伏,像深深的叹息
|
|
/// </summary>
|
|
private float GenerateEmotionWave(float time, float normalizedX)
|
|
{
|
|
// 使用更慢的时间流逝,让波形看起来更低沉
|
|
float slowTime = time * 0.3f; // 慢3倍
|
|
float t = slowTime % 1f;
|
|
if (t < 0) t += 1f;
|
|
|
|
// 主波:非常缓慢的正弦波(深沉的悲伤)
|
|
float sadnessBase = Mathf.Sin(t * Mathf.PI * 2f) * 0.5f;
|
|
|
|
// 第二层:更慢的起伏(压抑感)
|
|
float depression = Mathf.Sin(t * Mathf.PI * 0.8f) * 0.25f;
|
|
|
|
// 微弱的焦虑颤抖(但很轻微)
|
|
float anxiety = Mathf.Sin(t * Mathf.PI * 4f + normalizedX) * 0.1f;
|
|
anxiety *= (0.5f + Mathf.Sin(t * Mathf.PI) * 0.3f);
|
|
|
|
// 组合,整体偏向负值(下沉感)
|
|
float result = sadnessBase + depression + anxiety - 0.15f;
|
|
|
|
// 偶尔的深深叹息
|
|
if (t > 0.6f && t < 0.8f)
|
|
{
|
|
float sigh = -Mathf.Sin((t - 0.6f) / 0.2f * Mathf.PI) * 0.4f;
|
|
result += sigh;
|
|
}
|
|
|
|
return Mathf.Clamp(result, -1f, 1f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 逻辑波形 - 清晰的方波
|
|
/// </summary>
|
|
private float GenerateLogicWave(float time)
|
|
{
|
|
float t = time % 1f;
|
|
if (t < 0) t += 1f;
|
|
|
|
float amplitude = 0.7f;
|
|
float squareWave = t < 0.5f ? amplitude : -amplitude;
|
|
|
|
// 非常短的边缘过渡
|
|
float edgeSmooth = 0.015f;
|
|
if (t < edgeSmooth)
|
|
{
|
|
squareWave = Mathf.Lerp(-amplitude, amplitude, t / edgeSmooth);
|
|
}
|
|
else if (t > 0.5f - edgeSmooth && t < 0.5f + edgeSmooth)
|
|
{
|
|
float localT = (t - (0.5f - edgeSmooth)) / (edgeSmooth * 2f);
|
|
squareWave = Mathf.Lerp(amplitude, -amplitude, localT);
|
|
}
|
|
else if (t > 1f - edgeSmooth)
|
|
{
|
|
squareWave = Mathf.Lerp(-amplitude, amplitude, (t - (1f - edgeSmooth)) / edgeSmooth);
|
|
}
|
|
|
|
return squareWave;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 笑话波形 - 高频、尖锐、跳动
|
|
/// 特征:快速的脉冲、突然的尖峰、亢奋的跳动
|
|
/// </summary>
|
|
private float GenerateJokeWave(float time, float normalizedX)
|
|
{
|
|
// 使用更快的时间,让波形看起来更尖锐跳动
|
|
float fastTime = time * 2.5f; // 快2.5倍
|
|
float t = fastTime % 1f;
|
|
if (t < 0) t += 1f;
|
|
|
|
// 快速三角脉冲(尖锐的笑声节奏)
|
|
float pulsePhase = (t * 4f) % 1f; // 每周期4个脉冲
|
|
float pulse = 0f;
|
|
if (pulsePhase < 0.1f)
|
|
{
|
|
// 非常快速的上升
|
|
pulse = pulsePhase / 0.1f;
|
|
}
|
|
else if (pulsePhase < 0.2f)
|
|
{
|
|
// 快速下降
|
|
pulse = 1f - (pulsePhase - 0.1f) / 0.1f;
|
|
}
|
|
pulse *= 0.9f;
|
|
|
|
// 高频振荡(尖锐感)
|
|
float highFreq = Mathf.Sin(t * Mathf.PI * 12f) * 0.35f;
|
|
|
|
// 随机尖峰(突然的"笑点"爆发)
|
|
float spike = 0f;
|
|
float spikeT = (t * 7f) % 1f;
|
|
if (spikeT < 0.08f)
|
|
{
|
|
spike = Mathf.Sin(spikeT / 0.08f * Mathf.PI) * 0.5f;
|
|
}
|
|
|
|
// 额外的高频颤动(亢奋感)
|
|
float tremor = Mathf.Sin(t * Mathf.PI * 25f + normalizedX * 5f) * 0.12f;
|
|
|
|
float result = pulse + highFreq + spike + tremor;
|
|
|
|
return Mathf.Clamp(result, -1f, 1f);
|
|
}
|
|
|
|
private float GenerateFilterOutput(float time, float normalizedX)
|
|
{
|
|
float logic = GenerateLogicWave(time);
|
|
float joke = GenerateJokeWave(time, normalizedX);
|
|
|
|
float effectiveLogicWeight = _logicWeight;
|
|
float effectiveJokeWeight = _jokeWeight * _synthesisProgress;
|
|
|
|
float result = logic * effectiveLogicWeight + joke * effectiveJokeWeight;
|
|
|
|
return Mathf.Clamp(result, -1f, 1f);
|
|
}
|
|
|
|
private float GenerateNormalOutput(float time, float normalizedX)
|
|
{
|
|
float logic = GenerateLogicWave(time) * 0.4f;
|
|
float emotion = GenerateEmotionWave(time, normalizedX) * 0.4f;
|
|
float result = logic + emotion;
|
|
result += Mathf.Sin(time * Mathf.PI * 3f) * 0.1f;
|
|
|
|
return Mathf.Clamp(result, -1f, 1f);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 公共方法
|
|
|
|
/// <summary>
|
|
/// 设置清晰度(0=完全噪波, 1=完全清晰)
|
|
/// </summary>
|
|
public void SetClarity(float value)
|
|
{
|
|
clarity = Mathf.Clamp01(value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置清晰位置(进度条位置,0-1)
|
|
/// </summary>
|
|
public void SetClarityPosition(float position)
|
|
{
|
|
clarityPosition = Mathf.Clamp01(position);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置清晰区域宽度
|
|
/// </summary>
|
|
public void SetClarityWidth(float width)
|
|
{
|
|
clarityWidth = Mathf.Clamp(width, 0.01f, 0.5f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置噪波强度
|
|
/// </summary>
|
|
public void SetNoiseAmount(float amount)
|
|
{
|
|
noiseAmount = Mathf.Clamp01(amount);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查当前位置是否清晰(用于锁定检测)
|
|
/// </summary>
|
|
public bool IsPositionClear(float position, float threshold = 0.8f)
|
|
{
|
|
float localClarity = CalculateLocalClarity(position);
|
|
return localClarity >= threshold;
|
|
}
|
|
|
|
public void ApplySettings(WaveformSettings settings)
|
|
{
|
|
waveType = settings.waveType;
|
|
waveHeight = settings.waveHeight;
|
|
waveSpeed = settings.waveSpeed;
|
|
frequency = settings.frequency;
|
|
primaryColor = settings.primaryColor;
|
|
secondaryColor = settings.secondaryColor;
|
|
UpdateColors();
|
|
}
|
|
|
|
public void SetWaveType(WaveformType type)
|
|
{
|
|
waveType = type;
|
|
_isTransforming = false;
|
|
}
|
|
|
|
public void SetColors(Color primary, Color secondary)
|
|
{
|
|
primaryColor = primary;
|
|
secondaryColor = secondary;
|
|
UpdateColors();
|
|
}
|
|
|
|
public void StartTransform(WaveformType fromType, WaveformType toType)
|
|
{
|
|
_transformFromType = fromType;
|
|
_transformToType = toType;
|
|
_transformProgress = 0f;
|
|
_isTransforming = true;
|
|
}
|
|
|
|
public void UpdateTransformProgress(float progress)
|
|
{
|
|
_transformProgress = Mathf.Clamp01(progress);
|
|
if (_transformProgress >= 1f)
|
|
{
|
|
waveType = _transformToType;
|
|
_isTransforming = false;
|
|
}
|
|
}
|
|
|
|
public void FinishTransform()
|
|
{
|
|
waveType = _transformToType;
|
|
_transformProgress = 1f;
|
|
_isTransforming = false;
|
|
}
|
|
|
|
public void SetSynthesisWeights(float logicWeight, float jokeWeight)
|
|
{
|
|
_logicWeight = Mathf.Clamp01(logicWeight);
|
|
_jokeWeight = Mathf.Clamp01(jokeWeight);
|
|
}
|
|
|
|
public void SetSynthesisProgress(float progress)
|
|
{
|
|
_synthesisProgress = Mathf.Clamp01(progress);
|
|
}
|
|
|
|
public void SetVisible(bool visible)
|
|
{
|
|
if (_lineRenderer != null)
|
|
_lineRenderer.enabled = visible;
|
|
if (glowPointRenderer != null)
|
|
glowPointRenderer.enabled = visible;
|
|
}
|
|
|
|
public void SetAlpha(float alpha)
|
|
{
|
|
_currentAlpha = Mathf.Clamp01(alpha);
|
|
if (_lineRenderer == null) return;
|
|
|
|
Color startColor = primaryColor;
|
|
Color endColor = secondaryColor;
|
|
startColor.a = _currentAlpha;
|
|
endColor.a = _currentAlpha;
|
|
|
|
Gradient gradient = new Gradient();
|
|
gradient.SetKeys(
|
|
new GradientColorKey[] { new GradientColorKey(startColor, 0f), new GradientColorKey(endColor, 1f) },
|
|
new GradientAlphaKey[] { new GradientAlphaKey(_currentAlpha, 0f), new GradientAlphaKey(_currentAlpha, 1f) }
|
|
);
|
|
_lineRenderer.colorGradient = gradient;
|
|
|
|
if (glowPointRenderer != null)
|
|
{
|
|
Color glowColor = primaryColor;
|
|
glowColor.a = _currentAlpha;
|
|
glowPointRenderer.color = glowColor;
|
|
}
|
|
}
|
|
|
|
private void UpdateColors()
|
|
{
|
|
if (_lineRenderer == null) return;
|
|
|
|
// 获取实际颜色(优先使用Config预览)
|
|
Color actualPrimaryColor = primaryColor;
|
|
Color actualSecondaryColor = secondaryColor;
|
|
|
|
bool isEditor = !Application.isPlaying;
|
|
if (isEditor && previewFromConfig != ConfigPreviewType.None && previewConfig != null)
|
|
{
|
|
WaveformSettings settings = GetPreviewSettings();
|
|
if (settings != null)
|
|
{
|
|
actualPrimaryColor = settings.primaryColor;
|
|
actualSecondaryColor = settings.secondaryColor;
|
|
}
|
|
}
|
|
|
|
Gradient gradient = new Gradient();
|
|
gradient.SetKeys(
|
|
new GradientColorKey[] { new GradientColorKey(actualPrimaryColor, 0f), new GradientColorKey(actualSecondaryColor, 1f) },
|
|
new GradientAlphaKey[] { new GradientAlphaKey(_currentAlpha, 0f), new GradientAlphaKey(_currentAlpha, 1f) }
|
|
);
|
|
_lineRenderer.colorGradient = gradient;
|
|
|
|
if (glowPointRenderer != null)
|
|
{
|
|
glowPointRenderer.color = actualPrimaryColor;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|