From 0bcdcba8a1e896136f74825ecd200bc94e84a7d2 Mon Sep 17 00:00:00 2001
From: bottlefish <781230111@qq.com>
Date: Thu, 12 Mar 2026 15:24:46 +0800
Subject: [PATCH] =?UTF-8?q?fix(fix):=20=E8=B0=83=E6=95=B4=E5=AF=B9?=
=?UTF-8?q?=E8=AF=9D=E6=B0=94=E6=B3=A1=E5=8A=A0=E8=BD=BD=E6=97=B6=E6=9C=BA?=
=?UTF-8?q?=E4=B8=8E=E9=94=80=E5=94=AE=E6=80=81=E6=A7=BD=E4=BD=8D=E4=BC=98?=
=?UTF-8?q?=E5=85=88=E7=BA=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Enter 中先 LoadBubbles 再 SwitchCamera,避免 me: 释放log 时找不到 Player 槽位。
SalesState 中优先使用 salesManager.bubbleSlotGroup,缺失时回退 ScreenSystem。
Made-with: Cursor
---
.../HuoShan/SalesSystem/CrankController.cs | 73 ++++++++++++++++++-
.../HuoShan/SalesSystem/SalesYarnCommand.cs | 26 +++++++
.../UI/DialogUI/Bubbles/BubbleGroup.cs | 7 +-
3 files changed, 102 insertions(+), 4 deletions(-)
diff --git a/Assets/Scripts/MiniGame/HuoShan/SalesSystem/CrankController.cs b/Assets/Scripts/MiniGame/HuoShan/SalesSystem/CrankController.cs
index 47025f2ca..a8cca9d97 100644
--- a/Assets/Scripts/MiniGame/HuoShan/SalesSystem/CrankController.cs
+++ b/Assets/Scripts/MiniGame/HuoShan/SalesSystem/CrankController.cs
@@ -42,6 +42,13 @@ namespace AibisDream.MiniGame.HuoShan
[Tooltip("发条开始拖拽时触发")]
public UnityEvent onCrankStartDrag;
+ [Header("逆时针转圈表现")]
+ [Tooltip("逆时针转一圈的动画时长(秒)")]
+ [SerializeField] private float spinOnceDuration = 1f;
+
+ [Tooltip("逆时针转一圈完成后触发")]
+ public UnityEvent onSpinOnceComplete;
+
[Header("圆环/中心配置")]
[Tooltip("环中心(内环旋转中心),配置后发条将沿环轨道移动;不填则原地旋转")]
[SerializeField] private Transform ringCenter;
@@ -82,6 +89,9 @@ namespace AibisDream.MiniGame.HuoShan
private Vector3 _initialScale;
private Tweener _scaleTween;
private Tweener _returnTween;
+ private Tweener _spinTween;
+ private float _spinAngleOffset; // 逆时针转圈时的附加角度(0~360)
+ private bool _isSpinning; // 正在播放逆时针转圈
private float _effectiveRadius; // 实际使用的环半径
private bool _isReturning;
private float _returnSpeedPerSec; // 回位时的度/秒,匀速
@@ -298,7 +308,7 @@ namespace AibisDream.MiniGame.HuoShan
// 顺时针为正时,视觉上角度取反(数学角度逆时针为正)
float visualAngle = clockwisePositive ? -angle : angle;
- float positionAngle = startAngleOffset + visualAngle;
+ float positionAngle = startAngleOffset + visualAngle + _spinAngleOffset;
if (ringCenter != null && _effectiveRadius > 0f)
{
@@ -320,7 +330,8 @@ namespace AibisDream.MiniGame.HuoShan
}
else
{
- crankTransform.localRotation = Quaternion.Euler(0f, 0f, -visualAngle);
+ // 原地旋转:-visualAngle 为基础朝向,+_spinAngleOffset 为逆时针转圈叠加
+ crankTransform.localRotation = Quaternion.Euler(0f, 0f, -visualAngle + _spinAngleOffset);
}
}
@@ -353,6 +364,13 @@ namespace AibisDream.MiniGame.HuoShan
_returnTween.Kill();
_returnTween = null;
}
+ if (_spinTween != null)
+ {
+ _spinTween.Kill();
+ _spinTween = null;
+ _spinAngleOffset = 0f;
+ _isSpinning = false;
+ }
_isReturning = false;
// 拖拽缩放效果
@@ -435,7 +453,7 @@ namespace AibisDream.MiniGame.HuoShan
private void HandleReturn()
{
- if (!_isDragging && autoReturn && _currentRotation > 0f && !_isReturning)
+ if (!_isDragging && autoReturn && _currentRotation > 0f && !_isReturning && !_isSpinning)
{
_isReturning = true;
_returnSpeedPerSec = maxRotationAngle / Mathf.Max(0.01f, returnDuration);
@@ -467,6 +485,13 @@ namespace AibisDream.MiniGame.HuoShan
_returnTween.Kill();
_returnTween = null;
}
+ if (_spinTween != null)
+ {
+ _spinTween.Kill();
+ _spinTween = null;
+ }
+ _spinAngleOffset = 0f;
+ _isSpinning = false;
_isReturning = false;
_isDragging = false;
@@ -480,6 +505,43 @@ namespace AibisDream.MiniGame.HuoShan
}
}
+ ///
+ /// 逆时针转一圈的表现(可被 Yarn 命令、事件等触发)
+ ///
+ /// 动画时长,不传则使用 spinOnceDuration
+ public void PlaySpinCounterClockwise(float? duration = null)
+ {
+ float d = duration ?? spinOnceDuration;
+ if (d <= 0f) d = 0.5f;
+
+ if (_spinTween != null)
+ {
+ _spinTween.Kill();
+ _spinTween = null;
+ }
+
+ _spinAngleOffset = 0f;
+ _isSpinning = true;
+
+ _spinTween = DOTween.To(
+ () => _spinAngleOffset,
+ value =>
+ {
+ _spinAngleOffset = value;
+ ApplyCrankTransform(_currentRotation);
+ },
+ 360f,
+ d
+ ).SetEase(Ease.Linear).OnComplete(() =>
+ {
+ _spinAngleOffset = 0f;
+ _spinTween = null;
+ _isSpinning = false;
+ ApplyCrankTransform(_currentRotation);
+ onSpinOnceComplete?.Invoke();
+ });
+ }
+
///
/// 手动旋转到指定角度(用于动画或程序化控制)
///
@@ -532,6 +594,11 @@ namespace AibisDream.MiniGame.HuoShan
///
public bool HasTriggered => _hasTriggered;
+ ///
+ /// 是否正在播放逆时针转圈
+ ///
+ public bool IsSpinning => _isSpinning;
+
///
/// 回位时长(秒),供滑片等配合使用
///
diff --git a/Assets/Scripts/MiniGame/HuoShan/SalesSystem/SalesYarnCommand.cs b/Assets/Scripts/MiniGame/HuoShan/SalesSystem/SalesYarnCommand.cs
index e1a32cdfb..7d121d357 100644
--- a/Assets/Scripts/MiniGame/HuoShan/SalesSystem/SalesYarnCommand.cs
+++ b/Assets/Scripts/MiniGame/HuoShan/SalesSystem/SalesYarnCommand.cs
@@ -86,6 +86,32 @@ namespace AibisDream.MiniGame.HuoShan
Debug.Log("[SalesYarnCommand] 发条完成");
}
+ ///
+ /// 发条逆时针转一圈的表现
+ /// 用法: <> 或 <>
+ ///
+ /// 动画时长(秒),0 或不传则使用 CrankController 配置值
+ [YarnCommand("spin_crank")]
+ public static IEnumerator SpinCrank(float duration = 0f)
+ {
+ var crankController = GetSalesManager()?.CrankController;
+ if (crankController == null)
+ {
+ Debug.LogWarning("[SalesYarnCommand] 未找到CrankController");
+ yield break;
+ }
+
+ crankController.PlaySpinCounterClockwise(duration > 0f ? duration : null);
+
+ // 等待转圈完成
+ while (crankController.IsSpinning)
+ {
+ yield return null;
+ }
+
+ Debug.Log("[SalesYarnCommand] 发条逆时针转圈完成");
+ }
+
#endregion
#region 滑片控制命令
diff --git a/Assets/Scripts/UI/DialogUI/Bubbles/BubbleGroup.cs b/Assets/Scripts/UI/DialogUI/Bubbles/BubbleGroup.cs
index 69c707dcf..65c18e058 100644
--- a/Assets/Scripts/UI/DialogUI/Bubbles/BubbleGroup.cs
+++ b/Assets/Scripts/UI/DialogUI/Bubbles/BubbleGroup.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -55,6 +55,11 @@ namespace AibisDream
.Select(item => _bubbleFactory.Create(item))
.GroupBy(item => item.Role)
.ToDictionary(group => group.Key, group => group.ToArray());
+
+#if UNITY_EDITOR
+ var roleSummary = string.Join(", ", _bubbleDict.Select(kv => $"{kv.Key}({kv.Value.Length})"));
+ Debug.Log($"[BubbleGroup] 已加载 {groupData.dialogViewType}: {roleSummary}", this);
+#endif
}
#endregion