feat(huoshan): 扩展销售管理器功能和 Yarn 命令
This commit is contained in:
@@ -4,7 +4,9 @@ using Cinemachine;
|
||||
using AibisDream;
|
||||
using AibisDream.FixSystem;
|
||||
using AibisDream.Framework;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using DG.Tweening;
|
||||
using AibisDream.MiniGame.HuoShan;
|
||||
|
||||
namespace AibisDream.MiniGame.Language
|
||||
@@ -49,6 +51,9 @@ namespace AibisDream.MiniGame.Language
|
||||
[Tooltip("每轮转动完成后调用的 Yarn 节点名,可通过 $salesTurnIndex 分支不同内容")]
|
||||
[SerializeField] private string crankCompleteNode = "销售模块转动完成";
|
||||
|
||||
[Tooltip("滑片开始转动时调用的 Yarn 节点名,配合 ChipModule 解释正在做的步骤,可通过 $salesTurnIndex 分支")]
|
||||
[SerializeField] private string crankSlideStartNode = "销售转动_开始";
|
||||
|
||||
// [Header("销售模块深入 - 阶段事件(滑片进度阈值)")]
|
||||
// [Tooltip("语义组织阶段时调用的 Yarn 节点名(滑片进度 ≥ 1/3)")]
|
||||
// [SerializeField] private string phaseSemanticNode = "语义组织达到";
|
||||
@@ -59,7 +64,37 @@ namespace AibisDream.MiniGame.Language
|
||||
// [Tooltip("风格阶段时调用的 Yarn 节点名(滑片进度 ≥ 1)")]
|
||||
// [SerializeField] private string phaseStyleNode = "风格达到";
|
||||
|
||||
[Header("处理器深入模式")]
|
||||
[Tooltip("盖子 SpriteRenderer(深入模式下淡出)")]
|
||||
[SerializeField] private SpriteRenderer processorCover;
|
||||
|
||||
[Tooltip("旋钮控制器(不填则从 saleView 下查找)")]
|
||||
[SerializeField] private KnobController knobController;
|
||||
|
||||
[Tooltip("辉光管粒子效果(不填则从 saleView 下查找)")]
|
||||
[SerializeField] private GlowTubeEffect glowTubeEffect;
|
||||
|
||||
[Header("SaleView 进入动画")]
|
||||
[Tooltip("进入动画控制器(不填则从 saleView 下查找 SaleViewEnterAnimation)")]
|
||||
[SerializeField] private SaleViewEnterAnimation saleViewEnterAnimation;
|
||||
|
||||
[Tooltip("深入模式缩放倍数")]
|
||||
[SerializeField] private float deepModeScale = 1.2f;
|
||||
|
||||
[Tooltip("深入模式 X 偏移(负方向)")]
|
||||
[SerializeField] private float deepModeOffsetX = -5f;
|
||||
|
||||
[Tooltip("深入模式动画时长")]
|
||||
[SerializeField] private float deepModeTransitionDuration = 0.6f;
|
||||
|
||||
[Tooltip("盖子淡出时长")]
|
||||
[SerializeField] private float coverFadeDuration = 0.5f;
|
||||
|
||||
private readonly List<CameraEnum> registeredCameras = new();
|
||||
private bool _isProcessorDeepMode;
|
||||
private Vector3 _saleViewOriginalPos;
|
||||
private Vector3 _saleViewOriginalScale;
|
||||
private Sequence _deepModeSequence;
|
||||
|
||||
private int _currentTurnIndex; // 当前已完成第几轮(1-based)
|
||||
|
||||
@@ -78,6 +113,15 @@ namespace AibisDream.MiniGame.Language
|
||||
/// <summary>滑片控制器(供 Yarn 命令等通过 SalesManager 获取)</summary>
|
||||
public SliderController SliderController => sliderController;
|
||||
|
||||
/// <summary>旋钮控制器</summary>
|
||||
public KnobController KnobController => knobController;
|
||||
|
||||
/// <summary>辉光管效果</summary>
|
||||
public GlowTubeEffect GlowTubeEffect => glowTubeEffect;
|
||||
|
||||
/// <summary>是否处于处理器深入模式</summary>
|
||||
public bool IsProcessorDeepMode => _isProcessorDeepMode;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 对话气泡槽组(SaleSystem 下名为 "Bubble Slots" 的 GameObject)
|
||||
@@ -99,12 +143,17 @@ namespace AibisDream.MiniGame.Language
|
||||
RegisterToSystem();
|
||||
RegisterCameras();
|
||||
FindSaleView();
|
||||
FindSaleViewEnterAnimation();
|
||||
FindCrankController();
|
||||
FindSliderController();
|
||||
FindKnobController();
|
||||
FindGlowTubeEffect();
|
||||
FindProcessorCover();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_deepModeSequence?.Kill();
|
||||
UnregisterCameras();
|
||||
UnsubscribeFromCrankSlider();
|
||||
}
|
||||
@@ -137,6 +186,18 @@ namespace AibisDream.MiniGame.Language
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找 SaleView 进入动画(从 saleView 下查找)
|
||||
/// </summary>
|
||||
private void FindSaleViewEnterAnimation()
|
||||
{
|
||||
if (saleViewEnterAnimation != null) return;
|
||||
var root = saleView != null ? saleView.transform : transform;
|
||||
saleViewEnterAnimation = root.GetComponentInChildren<SaleViewEnterAnimation>(true);
|
||||
if (saleViewEnterAnimation != null)
|
||||
Debug.Log("[SalesManager] 找到 SaleViewEnterAnimation");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找发条控制器(从 saleView 或自身下查找)
|
||||
/// </summary>
|
||||
@@ -228,6 +289,11 @@ namespace AibisDream.MiniGame.Language
|
||||
#endif
|
||||
if (_currentTurnIndex > totalTurns) return;
|
||||
|
||||
// 滑片开始转动前,先触发 ChipModule 解释当前步骤(Stage3 等配合)
|
||||
StorageSystem.Instance?.SetValue("$salesTurnIndex", (float)_currentTurnIndex);
|
||||
if (!string.IsNullOrEmpty(crankSlideStartNode))
|
||||
DialogController.Instance?.StartDialogNode(crankSlideStartNode);
|
||||
|
||||
if (sliderController != null)
|
||||
{
|
||||
// 滑片移动至当前轮对应的段,时长与发条回位一致
|
||||
@@ -337,6 +403,7 @@ namespace AibisDream.MiniGame.Language
|
||||
if (saleView != null)
|
||||
{
|
||||
saleView.SetActive(true);
|
||||
saleViewEnterAnimation?.PlayEnterAnimation();
|
||||
Debug.Log("[SalesManager] 销售系统已打开");
|
||||
}
|
||||
else
|
||||
@@ -351,6 +418,7 @@ namespace AibisDream.MiniGame.Language
|
||||
public void CloseView()
|
||||
{
|
||||
UnsubscribeFromCrankSlider();
|
||||
saleViewEnterAnimation?.ResetToIdle();
|
||||
if (saleView != null)
|
||||
{
|
||||
saleView.SetActive(false);
|
||||
@@ -388,5 +456,167 @@ namespace AibisDream.MiniGame.Language
|
||||
sliderController?.ResetPosition();
|
||||
ResetPhase();
|
||||
}
|
||||
|
||||
#region 处理器深入模式
|
||||
|
||||
private void FindKnobController()
|
||||
{
|
||||
if (knobController != null) return;
|
||||
var root = saleView != null ? saleView.transform : transform;
|
||||
knobController = root.GetComponentInChildren<KnobController>(true);
|
||||
if (knobController == null)
|
||||
knobController = GetComponentInChildren<KnobController>(true);
|
||||
if (knobController != null)
|
||||
Debug.Log("[SalesManager] Found KnobController");
|
||||
}
|
||||
|
||||
private void FindGlowTubeEffect()
|
||||
{
|
||||
if (glowTubeEffect != null) return;
|
||||
var root = saleView != null ? saleView.transform : transform;
|
||||
glowTubeEffect = root.GetComponentInChildren<GlowTubeEffect>(true);
|
||||
if (glowTubeEffect == null)
|
||||
glowTubeEffect = GetComponentInChildren<GlowTubeEffect>(true);
|
||||
if (glowTubeEffect != null)
|
||||
Debug.Log("[SalesManager] Found GlowTubeEffect");
|
||||
}
|
||||
|
||||
private void FindProcessorCover()
|
||||
{
|
||||
if (processorCover != null) return;
|
||||
var root = saleView != null ? saleView.transform : transform;
|
||||
foreach (var t in root.GetComponentsInChildren<Transform>(true))
|
||||
{
|
||||
if (t.name == "\u76d6\u5b50")
|
||||
{
|
||||
processorCover = t.GetComponent<SpriteRenderer>();
|
||||
if (processorCover != null)
|
||||
Debug.Log("[SalesManager] Found processor cover");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 进入处理器深入模式:面板放大右移 → 盖子淡出 → 启动旋钮和辉光管
|
||||
/// </summary>
|
||||
public void EnterProcessorDeepMode()
|
||||
{
|
||||
if (_isProcessorDeepMode) return;
|
||||
if (saleView == null)
|
||||
{
|
||||
Debug.LogError("[SalesManager] SaleView is null, cannot enter processor deep mode", this);
|
||||
return;
|
||||
}
|
||||
|
||||
_isProcessorDeepMode = true;
|
||||
StartCoroutine(EnterProcessorDeepModeRoutine());
|
||||
}
|
||||
|
||||
private IEnumerator EnterProcessorDeepModeRoutine()
|
||||
{
|
||||
_deepModeSequence?.Kill();
|
||||
|
||||
var viewTransform = saleView.transform;
|
||||
_saleViewOriginalPos = viewTransform.localPosition;
|
||||
_saleViewOriginalScale = viewTransform.localScale;
|
||||
|
||||
// Activate cover so we can fade it out
|
||||
if (processorCover != null)
|
||||
{
|
||||
processorCover.gameObject.SetActive(true);
|
||||
var c = processorCover.color;
|
||||
processorCover.color = new Color(c.r, c.g, c.b, 1f);
|
||||
}
|
||||
|
||||
// Build animation sequence
|
||||
_deepModeSequence = DOTween.Sequence();
|
||||
|
||||
// Step 1: Scale up + shift X
|
||||
Vector3 targetPos = _saleViewOriginalPos + new Vector3(deepModeOffsetX, 0f, 0f);
|
||||
Vector3 targetScale = _saleViewOriginalScale * deepModeScale;
|
||||
|
||||
_deepModeSequence.Append(
|
||||
viewTransform.DOLocalMove(targetPos, deepModeTransitionDuration).SetEase(Ease.OutCubic)
|
||||
);
|
||||
_deepModeSequence.Join(
|
||||
viewTransform.DOScale(targetScale, deepModeTransitionDuration).SetEase(Ease.OutCubic)
|
||||
);
|
||||
|
||||
// Step 2: Fade out cover
|
||||
if (processorCover != null)
|
||||
{
|
||||
_deepModeSequence.Append(
|
||||
processorCover.DOFade(0f, coverFadeDuration).SetEase(Ease.InQuad)
|
||||
);
|
||||
_deepModeSequence.AppendCallback(() =>
|
||||
{
|
||||
processorCover.gameObject.SetActive(false);
|
||||
});
|
||||
}
|
||||
|
||||
// Step 3: Enable knob + glow tube
|
||||
_deepModeSequence.AppendCallback(() =>
|
||||
{
|
||||
if (glowTubeEffect != null) glowTubeEffect.gameObject.SetActive(true);
|
||||
if (knobController != null)
|
||||
{
|
||||
knobController.gameObject.SetActive(true);
|
||||
knobController.Reset();
|
||||
}
|
||||
Debug.Log("[SalesManager] Processor deep mode entered");
|
||||
});
|
||||
|
||||
yield return _deepModeSequence.WaitForCompletion();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出处理器深入模式:恢复面板位置/缩放、恢复盖子
|
||||
/// </summary>
|
||||
public void ExitProcessorDeepMode()
|
||||
{
|
||||
if (!_isProcessorDeepMode) return;
|
||||
_isProcessorDeepMode = false;
|
||||
StartCoroutine(ExitProcessorDeepModeRoutine());
|
||||
}
|
||||
|
||||
private IEnumerator ExitProcessorDeepModeRoutine()
|
||||
{
|
||||
_deepModeSequence?.Kill();
|
||||
|
||||
if (knobController != null) knobController.gameObject.SetActive(false);
|
||||
if (glowTubeEffect != null) glowTubeEffect.gameObject.SetActive(false);
|
||||
|
||||
_deepModeSequence = DOTween.Sequence();
|
||||
|
||||
// Restore cover
|
||||
if (processorCover != null)
|
||||
{
|
||||
processorCover.gameObject.SetActive(true);
|
||||
var c = processorCover.color;
|
||||
processorCover.color = new Color(c.r, c.g, c.b, 0f);
|
||||
_deepModeSequence.Append(
|
||||
processorCover.DOFade(1f, coverFadeDuration).SetEase(Ease.OutQuad)
|
||||
);
|
||||
}
|
||||
|
||||
// Restore position and scale
|
||||
var viewTransform = saleView.transform;
|
||||
_deepModeSequence.Append(
|
||||
viewTransform.DOLocalMove(_saleViewOriginalPos, deepModeTransitionDuration).SetEase(Ease.InOutCubic)
|
||||
);
|
||||
_deepModeSequence.Join(
|
||||
viewTransform.DOScale(_saleViewOriginalScale, deepModeTransitionDuration).SetEase(Ease.InOutCubic)
|
||||
);
|
||||
|
||||
_deepModeSequence.AppendCallback(() =>
|
||||
{
|
||||
Debug.Log("[SalesManager] Processor deep mode exited");
|
||||
});
|
||||
|
||||
yield return _deepModeSequence.WaitForCompletion();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace AibisDream.MiniGame.HuoShan
|
||||
if (sliderController != null)
|
||||
{
|
||||
Debug.Log($"[SalesYarnCommand] 移动滑片到位置{normalizedPosition},时长{duration}秒");
|
||||
|
||||
|
||||
sliderController.SlideToNormalized(normalizedPosition, duration);
|
||||
yield return new WaitForSeconds(duration);
|
||||
}
|
||||
@@ -322,18 +322,50 @@ namespace AibisDream.MiniGame.HuoShan
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 进入处理器深入模式(面板右移)
|
||||
/// 进入处理器深入模式(面板放大右移 + 盖子淡出 + 旋钮/辉光管启动)
|
||||
/// 用法: <<enter_processor_mode>>
|
||||
/// </summary>
|
||||
[YarnCommand("enter_processor_mode")]
|
||||
public static IEnumerator EnterProcessorMode()
|
||||
{
|
||||
Debug.Log("[SalesYarnCommand] 进入处理器深入模式");
|
||||
var manager = GetSalesManager();
|
||||
if (manager == null)
|
||||
{
|
||||
Debug.LogWarning("[SalesYarnCommand] SalesManager not found");
|
||||
yield break;
|
||||
}
|
||||
|
||||
// 触发面板右移动画
|
||||
// 可以使用DOTween或Timeline
|
||||
Debug.Log("[SalesYarnCommand] Entering processor deep mode");
|
||||
manager.EnterProcessorDeepMode();
|
||||
|
||||
yield return new WaitForSeconds(1f);
|
||||
while (manager.IsProcessorDeepMode == false)
|
||||
yield return null;
|
||||
|
||||
// Wait a frame for everything to settle
|
||||
yield return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出处理器深入模式(恢复面板位置/缩放、恢复盖子)
|
||||
/// 用法: <<exit_processor_mode>>
|
||||
/// </summary>
|
||||
[YarnCommand("exit_processor_mode")]
|
||||
public static IEnumerator ExitProcessorMode()
|
||||
{
|
||||
var manager = GetSalesManager();
|
||||
if (manager == null)
|
||||
{
|
||||
Debug.LogWarning("[SalesYarnCommand] SalesManager not found");
|
||||
yield break;
|
||||
}
|
||||
|
||||
Debug.Log("[SalesYarnCommand] Exiting processor deep mode");
|
||||
manager.ExitProcessorDeepMode();
|
||||
|
||||
while (manager.IsProcessorDeepMode)
|
||||
yield return null;
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user