diff --git a/Assets/Scripts/MiniGame/HuoShan/SalesSystem/SliderController.cs b/Assets/Scripts/MiniGame/HuoShan/SalesSystem/SliderController.cs
index 6d1853df6..4aa32ad07 100644
--- a/Assets/Scripts/MiniGame/HuoShan/SalesSystem/SliderController.cs
+++ b/Assets/Scripts/MiniGame/HuoShan/SalesSystem/SliderController.cs
@@ -6,11 +6,11 @@ using DG.Tweening;
namespace AibisDream.MiniGame.HuoShan
{
///
- /// 滑片控制器 - 实现滑片沿圆环滑动以及与波形联动
+ /// 滑片控制器 - 实现滑片沿圆环滑动
/// 功能:
/// - 仅通过Yarn指令控制移动,不接受玩家直接交互
- /// - 滑片角度/弧度驱动波形参数
/// - 等离子体发光段:从起始位置到当前位置显示等离子体进度指示
+ /// - 位置变化通过 onSliderPositionChanged 通知(EmotionWaveManager 等可订阅)
///
public class SliderController : MonoBehaviour
{
@@ -75,17 +75,6 @@ namespace AibisDream.MiniGame.HuoShan
[Tooltip("粒子渲染 Sorting Order")]
[SerializeField] private int plasmaSortingOrder = 51;
- [Header("兼容旧版 LineRenderer(可留空)")]
- [Tooltip("若存在则禁用,改用 ParticleSystem")]
- [SerializeField] private LineRenderer plasmaLineRenderer;
-
- [Header("波形联动")]
- [Tooltip("波形检测器引用")]
- [SerializeField] private WaveformDetector waveformDetector;
-
- [Tooltip("等离子体发光影响波形参数")]
- [SerializeField] private bool plasmaAffectsWaveform = true;
-
[Header("事件")]
[Tooltip("滑片位置改变时触发(参数:标准化位置0-1)")]
public UnityEvent onSliderPositionChanged;
@@ -103,7 +92,7 @@ namespace AibisDream.MiniGame.HuoShan
public UnityEvent onSlideComplete;
[Header("调试测试")]
- [Tooltip("勾选后,拖拽下方滑块可直接测试滑片与弧线(Play 模式下生效);有程序控制滑动时会自动跳过")]
+ [Tooltip("勾选后,拖拽下方滑块可直接测试滑片与弧线(Play 模式下生效,优先于程序控制)")]
[SerializeField] private bool useTestSlider;
[Tooltip("测试用滑块:0=起始位置,1=终点位置")]
@@ -111,7 +100,6 @@ namespace AibisDream.MiniGame.HuoShan
private float _currentAngle = 0f;
private float _targetAngle = 0f;
- private WaveformRenderer _waveformRenderer;
private bool _phaseSemanticFired;
private bool _phaseReviewFired;
private bool _phaseStyleFired;
@@ -132,20 +120,8 @@ namespace AibisDream.MiniGame.HuoShan
sliderTransform = transform;
}
- // 禁用旧版 LineRenderer(改用 ParticleSystem)
- if (plasmaLineRenderer != null)
- {
- plasmaLineRenderer.enabled = false;
- }
-
// 初始化等离子体粒子系统
EnsurePlasmaParticleSystem();
-
- // 获取波形渲染器
- if (waveformDetector != null && waveformDetector.IsShown)
- {
- _waveformRenderer = waveformDetector.GetComponentInChildren();
- }
}
private void Update()
@@ -166,22 +142,16 @@ namespace AibisDream.MiniGame.HuoShan
#region 位置更新
- private void UpdateSliderPosition()
+ ///
+ /// 根据角度应用滑片位置与旋转(顺时针移动:角度取负)
+ ///
+ /// 滑片世界坐标
+ private Vector3 ApplyAngleToTransform(float angle)
{
-#if UNITY_EDITOR
- // 调试模式:Inspector 滑块直接驱动滑片(有程序控制的滑动时跳过,避免覆盖 crank 驱动)
- if (useTestSlider && Application.isPlaying && (_moveTween == null || !_moveTween.IsActive()))
- {
- _targetAngle = testSliderPosition * slideAngleRange;
- }
-#endif
+ if (ringCenter == null || sliderTransform == null) return _lastValidPosition;
- // 匀速移动到目标角度(避免 Lerp 导致的越接近越慢、卡顿感)
- float maxDelta = slideSpeed * Time.deltaTime;
- _currentAngle = Mathf.MoveTowards(_currentAngle, _targetAngle, maxDelta);
-
- // 计算滑片在世界空间的位置
- float radian = (_currentAngle + startAngleOffset) * Mathf.Deg2Rad;
+ // 顺时针:标准数学角度增加为逆时针,取负则为顺时针
+ float radian = -(angle + startAngleOffset) * Mathf.Deg2Rad;
Vector3 position = ringCenter.position + new Vector3(
Mathf.Cos(radian) * outerRadius,
Mathf.Sin(radian) * outerRadius,
@@ -190,12 +160,39 @@ namespace AibisDream.MiniGame.HuoShan
sliderTransform.position = position;
- // 滑片沿轨道顺时针方向(切线方向,与逆时针相反)
+ // 滑片沿轨道顺时针方向(切线方向)
Vector3 direction = position - ringCenter.position;
float radialAngle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
float tangentAngle = radialAngle - 90f; // 顺时针切线
sliderTransform.rotation = Quaternion.Euler(0f, 0f, tangentAngle);
+ return position;
+ }
+
+ private void UpdateSliderPosition()
+ {
+#if UNITY_EDITOR
+ // 调试模式:Inspector 滑块直接驱动滑片,勾选后始终优先(覆盖程序控制)
+ if (useTestSlider && Application.isPlaying)
+ {
+ if (_moveTween != null && _moveTween.IsActive())
+ {
+ _moveTween.Kill();
+ _moveTween = null;
+ }
+ _targetAngle = testSliderPosition * slideAngleRange;
+ }
+#endif
+
+ // 匀速移动到目标角度(避免 Lerp 导致的越接近越慢、卡顿感)
+ float maxDelta = slideSpeed * Time.deltaTime;
+ _currentAngle = Mathf.MoveTowards(_currentAngle, _targetAngle, maxDelta);
+
+ if (ringCenter == null || sliderTransform == null) return;
+
+ // 计算滑片在世界空间的位置(顺时针:角度取负)
+ Vector3 position = ApplyAngleToTransform(_currentAngle);
+
// 夹子不跟随滑片移动,保持原位
// 触发位置改变事件
@@ -203,7 +200,6 @@ namespace AibisDream.MiniGame.HuoShan
if (Vector3.Distance(position, _lastValidPosition) > 0.01f)
{
onSliderPositionChanged?.Invoke(normalizedPosition);
- UpdateWaveform(normalizedPosition);
_lastValidPosition = position;
// 阶段阈值事件:1/3 语义组织, 2/3 审查, 1 风格
@@ -360,8 +356,9 @@ namespace AibisDream.MiniGame.HuoShan
return;
}
- float startRad = startAngleOffset * Mathf.Deg2Rad;
- float endRad = (startAngleOffset + _currentAngle) * Mathf.Deg2Rad;
+ // 顺时针:弧线从 startAngleOffset 向负角度延伸
+ float startRad = -startAngleOffset * Mathf.Deg2Rad;
+ float endRad = -(startAngleOffset + _currentAngle) * Mathf.Deg2Rad;
float arcSpan = endRad - startRad;
float z = sliderTransform != null ? sliderTransform.position.z : ringCenter.position.z;
@@ -405,34 +402,90 @@ namespace AibisDream.MiniGame.HuoShan
#endregion
- #region 波形联动
+ #region Gizmo 与编辑器
- private void UpdateWaveform(float normalizedPosition)
+ private void OnDrawGizmosSelected()
{
- if (!plasmaAffectsWaveform || waveformDetector == null) return;
+ var center = ringCenter != null ? ringCenter.position : transform.position;
+ float z = sliderTransform != null ? sliderTransform.position.z : center.z;
- // 将滑片位置映射到波形参数
- float waveformPosition = normalizedPosition;
+ // 外环
+ Gizmos.color = new Color(0.2f, 0.8f, 1f, 0.6f);
+ DrawCircleGizmo(center, outerRadius, z, 64);
- // 更新波形检测器的扫描位置
- if (waveformDetector.IsScanMode)
+ // 内环(等离子体弧线)
+ Gizmos.color = new Color(0.3f, 0.9f, 0.55f, 0.5f);
+ DrawCircleGizmo(center, innerRadius, z, 64);
+
+ // 起始位置标记(绿色)
+ float startRad = -(0f + startAngleOffset) * Mathf.Deg2Rad;
+ Vector3 startPos = center + new Vector3(Mathf.Cos(startRad) * outerRadius, Mathf.Sin(startRad) * outerRadius, 0f);
+ Gizmos.color = Color.green;
+ Gizmos.DrawWireSphere(startPos, outerRadius * 0.05f);
+
+ // 终点位置标记(黄色)
+ float endRad = -(slideAngleRange + startAngleOffset) * Mathf.Deg2Rad;
+ Vector3 endPos = center + new Vector3(Mathf.Cos(endRad) * outerRadius, Mathf.Sin(endRad) * outerRadius, 0f);
+ Gizmos.color = Color.yellow;
+ Gizmos.DrawWireSphere(endPos, outerRadius * 0.05f);
+
+ // 段分割线
+ Gizmos.color = new Color(1f, 1f, 0.5f, 0.3f);
+ float segAngle = slideAngleRange / Mathf.Max(1, segmentCount);
+ for (int i = 1; i < segmentCount; i++)
{
- // 如果处于扫描模式,更新扫描滑块
- // 这会是集成的一部分,具体实现需要根据游戏流程调整
+ float rad = -(i * segAngle + startAngleOffset) * Mathf.Deg2Rad;
+ Vector3 segPos = center + new Vector3(Mathf.Cos(rad) * outerRadius, Mathf.Sin(rad) * outerRadius, 0f);
+ Gizmos.DrawLine(center, segPos);
}
- // 更新波形渲染器
- if (_waveformRenderer != null)
+ // 当前滑片位置(红色,仅 Play 模式有值)
+#if UNITY_EDITOR
+ if (Application.isPlaying)
+#endif
{
- // 根据滑片位置调整波形清晰度
- float clarity = Mathf.Lerp(0f, 1f, normalizedPosition);
- _waveformRenderer.SetClarity(clarity);
-
- // 根据滑片位置调整波形位置
- _waveformRenderer.SetClarityPosition(normalizedPosition);
+ float curRad = -(_currentAngle + startAngleOffset) * Mathf.Deg2Rad;
+ Vector3 curPos = center + new Vector3(Mathf.Cos(curRad) * outerRadius, Mathf.Sin(curRad) * outerRadius, 0f);
+ Gizmos.color = Color.red;
+ Gizmos.DrawWireSphere(curPos, outerRadius * 0.08f);
}
}
+ private void DrawCircleGizmo(Vector3 center, float radius, float z, int segments)
+ {
+ Vector3 prev = center + new Vector3(radius, 0f, 0f);
+ for (int i = 1; i <= segments; i++)
+ {
+ float rad = (float)i / segments * Mathf.PI * 2f;
+ Vector3 next = center + new Vector3(Mathf.Cos(rad) * radius, Mathf.Sin(rad) * radius, 0f);
+ Gizmos.DrawLine(prev, next);
+ prev = next;
+ }
+ }
+
+ ///
+ /// 在编辑器中一键将滑片重置到初始状态
+ ///
+ [ContextMenu("重置到初始状态")]
+ private void ResetToInitialStateInEditor()
+ {
+ _targetAngle = 0f;
+ _currentAngle = 0f;
+ ResetPhaseFlags();
+ if (_moveTween != null && _moveTween.IsActive())
+ {
+ _moveTween.Kill();
+ _moveTween = null;
+ }
+ if (ringCenter != null && sliderTransform != null)
+ ApplyAngleToTransform(0f);
+#if UNITY_EDITOR
+ UnityEditor.EditorUtility.SetDirty(this);
+ if (gameObject.scene.IsValid())
+ UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(gameObject.scene);
+#endif
+ }
+
#endregion
#region 公共方法