2026-06-24 02:33:48 +08:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.Events;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 实验流程状态机——整个项目的核心控制器。
|
|
|
|
|
|
/// 负责步骤推进、模式切换、UI 更新、加权考核判分调度。
|
|
|
|
|
|
/// 挂在一个持久化的 GameObject 上。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class StepManager : MonoBehaviour
|
|
|
|
|
|
{
|
2026-06-24 06:05:55 +08:00
|
|
|
|
[Header("配置(优先级:Inspector直接赋值 > ExperimentFlowCoordinator兜底 > Resources加载)")]
|
2026-06-24 02:33:48 +08:00
|
|
|
|
public ExperimentConfig Config;
|
|
|
|
|
|
|
|
|
|
|
|
[Header("事件(拖入场景对象或通过代码绑定)")]
|
2026-06-24 06:05:55 +08:00
|
|
|
|
public UnityEvent<int> OnStepChanged;
|
|
|
|
|
|
public UnityEvent<string> OnTipChanged;
|
|
|
|
|
|
public UnityEvent<string> OnDialogueChanged;
|
|
|
|
|
|
public UnityEvent<StepData> OnExamPopup;
|
|
|
|
|
|
public UnityEvent<string> OnDetailedContent;
|
|
|
|
|
|
public UnityEvent OnExperimentComplete;
|
|
|
|
|
|
public UnityEvent<string, bool> OnVideoToggle;
|
|
|
|
|
|
public UnityEvent<bool> OnModeUIUpdate;
|
2026-06-24 02:33:48 +08:00
|
|
|
|
|
|
|
|
|
|
// 私有状态
|
|
|
|
|
|
private StepData[] _activeSteps;
|
|
|
|
|
|
private int _currentStepIndex = -1;
|
|
|
|
|
|
private ExperimentMode _mode;
|
|
|
|
|
|
private FixationMethod _fixation;
|
2026-06-24 06:05:55 +08:00
|
|
|
|
private bool _initialized = false;
|
2026-06-24 02:33:48 +08:00
|
|
|
|
|
|
|
|
|
|
public int CurrentStepIndex => _currentStepIndex;
|
|
|
|
|
|
public int TotalSteps => _activeSteps != null ? _activeSteps.Length : 0;
|
|
|
|
|
|
public ExperimentMode Mode => _mode;
|
|
|
|
|
|
public FixationMethod Fixation => _fixation;
|
2026-06-24 06:05:55 +08:00
|
|
|
|
public bool IsInitialized => _initialized;
|
2026-06-24 02:33:48 +08:00
|
|
|
|
|
2026-06-24 06:05:55 +08:00
|
|
|
|
/// <summary>用 GameManager 的当前设置初始化</summary>
|
2026-06-24 02:33:48 +08:00
|
|
|
|
public void InitializeFromGameManager()
|
|
|
|
|
|
{
|
|
|
|
|
|
var gm = GameManager.Instance;
|
|
|
|
|
|
if (gm == null) { Debug.LogError("StepManager: GameManager.Instance is null!"); return; }
|
|
|
|
|
|
Initialize(gm.CurrentExperimentType, gm.CurrentMode, gm.CurrentFixationMethod);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>显式指定参数初始化</summary>
|
|
|
|
|
|
public void Initialize(ExperimentType type, ExperimentMode mode, FixationMethod fixation)
|
|
|
|
|
|
{
|
2026-06-24 06:05:55 +08:00
|
|
|
|
// 如果 Inspector 里没有直接拖 Config,尝试从 ExperimentFlowCoordinator 获取兜底配置
|
|
|
|
|
|
if (Config == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var coordinator = FindObjectOfType<ExperimentFlowCoordinator>();
|
|
|
|
|
|
if (coordinator != null && coordinator.DefaultConfig != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Config = coordinator.DefaultConfig;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 最后尝试从 Resources 加载
|
|
|
|
|
|
if (Config == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Config = Resources.Load<ExperimentConfig>($"Configs/{type}Config");
|
|
|
|
|
|
}
|
2026-06-24 02:33:48 +08:00
|
|
|
|
|
|
|
|
|
|
if (Config == null)
|
|
|
|
|
|
{
|
2026-06-24 06:05:55 +08:00
|
|
|
|
Debug.LogError($"StepManager: 找不到 ExperimentConfig for {type}。" +
|
|
|
|
|
|
"请在 Inspector 中直接拖入 Config,或在 ExperimentFlowCoordinator 上设置 Default Config," +
|
|
|
|
|
|
"或在 Resources/Configs/ 下创建 ScriptableObject。");
|
2026-06-24 02:33:48 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-24 06:05:55 +08:00
|
|
|
|
_mode = mode;
|
|
|
|
|
|
_fixation = fixation;
|
|
|
|
|
|
|
2026-06-24 02:33:48 +08:00
|
|
|
|
_activeSteps = Config.GetStepsFor(mode, fixation);
|
|
|
|
|
|
if (_activeSteps == null || _activeSteps.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"StepManager: 实验 {type} 模式 {mode} 固定方式 {fixation} 无步骤数据!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_currentStepIndex = -1;
|
2026-06-24 06:05:55 +08:00
|
|
|
|
_initialized = true;
|
2026-06-24 02:33:48 +08:00
|
|
|
|
|
|
|
|
|
|
if (mode == ExperimentMode.Exam)
|
|
|
|
|
|
GameManager.Instance.InitExamRecord(_activeSteps.Length);
|
|
|
|
|
|
|
|
|
|
|
|
OnModeUIUpdate?.Invoke(mode == ExperimentMode.Exam);
|
|
|
|
|
|
GoToStep(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void GoToStep(int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_activeSteps == null) return;
|
|
|
|
|
|
index = Mathf.Clamp(index, 0, _activeSteps.Length - 1);
|
|
|
|
|
|
if (index == _currentStepIndex) return;
|
|
|
|
|
|
|
|
|
|
|
|
_currentStepIndex = index;
|
|
|
|
|
|
var step = _activeSteps[index];
|
|
|
|
|
|
|
|
|
|
|
|
if (_mode == ExperimentMode.Learn)
|
|
|
|
|
|
{
|
|
|
|
|
|
OnTipChanged?.Invoke(step.TipText);
|
|
|
|
|
|
OnDialogueChanged?.Invoke(step.DialogueText);
|
|
|
|
|
|
OnDetailedContent?.Invoke(step.DetailedContent);
|
|
|
|
|
|
if (step.ShowPipVideo)
|
|
|
|
|
|
OnVideoToggle?.Invoke(step.VideoFileName, true);
|
|
|
|
|
|
else
|
|
|
|
|
|
OnVideoToggle?.Invoke(null, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
OnTipChanged?.Invoke("");
|
|
|
|
|
|
OnDialogueChanged?.Invoke("");
|
|
|
|
|
|
OnDetailedContent?.Invoke("");
|
|
|
|
|
|
OnVideoToggle?.Invoke(null, false);
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(step.ExamQuestionText))
|
|
|
|
|
|
OnExamPopup?.Invoke(step);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
OnStepChanged?.Invoke(_currentStepIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void NextStep()
|
|
|
|
|
|
{
|
2026-07-08 09:38:42 +08:00
|
|
|
|
Debug.LogError("====== StepManager: 接收到 NextStep 指令! ======");
|
|
|
|
|
|
|
|
|
|
|
|
// 首先尝试是否存在可以点击的 3D 物品,如果有,优先执行 3D 交互
|
|
|
|
|
|
if (TryClickActiveHandler())
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("====== StepManager: 成功模拟 3D 物品点击,不进行常规的 NextStep 流程 ======");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Debug.Log("====== StepManager: 未找到 3D 物品,执行常规 NextStep 流程 ======");
|
|
|
|
|
|
|
|
|
|
|
|
if (_activeSteps != null && _currentStepIndex < _activeSteps.Length - 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
GoToStep(_currentStepIndex + 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (_activeSteps != null && _currentStepIndex == _activeSteps.Length - 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
CompleteExperiment();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void TryInteractCurrent3DStep()
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("====== StepManager: 接收到 3D 自动交互指令 ======");
|
|
|
|
|
|
if (TryClickActiveHandler()) return;
|
|
|
|
|
|
Debug.Log("====== StepManager: 当前没有可自动交互的 3D 物品 ======");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool TryClickActiveHandler()
|
|
|
|
|
|
{
|
2026-07-11 04:50:21 +08:00
|
|
|
|
var point2s = Object.FindObjectsOfType<Point2ClickHandler>();
|
|
|
|
|
|
foreach (var p in point2s)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (p.gameObject.activeInHierarchy && p.CanBeClicked())
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"====== StepManager: 模拟点击了 {p.name}! ======");
|
|
|
|
|
|
p.PerformClick();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-08 09:38:42 +08:00
|
|
|
|
var touches = Object.FindObjectsOfType<TouchPositionHandler>();
|
|
|
|
|
|
System.Array.Sort(touches, (a, b) => string.Compare(a.name, b.name));
|
|
|
|
|
|
foreach (var t in touches)
|
|
|
|
|
|
{
|
2026-07-09 02:49:38 +08:00
|
|
|
|
Debug.Log($"[StepManager] 检查 Touch: {t.name}, active={t.gameObject.activeInHierarchy}, CanBeClicked={t.CanBeClicked()}");
|
2026-07-08 09:38:42 +08:00
|
|
|
|
if (t.gameObject.activeInHierarchy && t.CanBeClicked())
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"====== StepManager: 模拟点击了 {t.name}! ======");
|
|
|
|
|
|
t.PerformClick();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var shoses = Object.FindObjectsOfType<ShoseClickHandler>();
|
|
|
|
|
|
foreach (var h in shoses)
|
|
|
|
|
|
{
|
2026-07-09 02:49:38 +08:00
|
|
|
|
Debug.Log($"[StepManager] 检查 Shose: {h.name}, active={h.gameObject.activeInHierarchy}, CanBeClicked={h.CanBeClicked()}");
|
2026-07-08 09:38:42 +08:00
|
|
|
|
if (h.gameObject.activeInHierarchy && h.CanBeClicked())
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"====== StepManager: 模拟点击了 {h.name}! ======");
|
|
|
|
|
|
h.PerformClick();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var chanraos = Object.FindObjectsOfType<ChanraoTuibuHandler>();
|
|
|
|
|
|
foreach (var h in chanraos)
|
|
|
|
|
|
{
|
2026-07-09 02:49:38 +08:00
|
|
|
|
Debug.Log($"[StepManager] 检查 Chanrao: {h.name}, active={h.gameObject.activeInHierarchy}, CanBeClicked={h.CanBeClicked()}");
|
2026-07-08 09:38:42 +08:00
|
|
|
|
if (h.gameObject.activeInHierarchy && h.CanBeClicked())
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"====== StepManager: 模拟点击了 {h.name}! ======");
|
|
|
|
|
|
h.PerformClick();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-07-17 05:42:52 +08:00
|
|
|
|
|
|
|
|
|
|
var splintObjects = Object.FindObjectsOfType<SplintObjectClickHandler>();
|
|
|
|
|
|
foreach (var h in splintObjects)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"[StepManager] 检查 SplintObject: {h.name}, active={h.gameObject.activeInHierarchy}, CanBeClicked={h.CanBeClicked()}");
|
|
|
|
|
|
if (h.gameObject.activeInHierarchy && h.CanBeClicked())
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"====== StepManager: 模拟点击了 {h.name}! ======");
|
|
|
|
|
|
h.PerformClick();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-07-08 09:38:42 +08:00
|
|
|
|
|
|
|
|
|
|
var pings = Object.FindObjectsOfType<PingClickHandler>();
|
|
|
|
|
|
System.Array.Sort(pings, (a, b) => string.Compare(b.name, a.name));
|
|
|
|
|
|
foreach (var p in pings)
|
|
|
|
|
|
{
|
2026-07-09 02:49:38 +08:00
|
|
|
|
Debug.Log($"[StepManager] 检查 Ping: {p.name}, active={p.gameObject.activeInHierarchy}, CanBeClicked={p.CanBeClicked()}");
|
2026-07-08 09:38:42 +08:00
|
|
|
|
if (p.gameObject.activeInHierarchy && p.CanBeClicked())
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError($"====== StepManager: 模拟点击了 {p.name}! ======");
|
|
|
|
|
|
p.PerformClick();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool TryUndoActiveHandler()
|
|
|
|
|
|
{
|
2026-07-09 03:16:00 +08:00
|
|
|
|
return ActionHistory.TryUndoLast();
|
2026-06-24 02:33:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-02 16:22:17 +08:00
|
|
|
|
|
2026-07-09 03:16:00 +08:00
|
|
|
|
public void RecordPingStep(int pingIndex, bool secondClick)
|
|
|
|
|
|
{
|
|
|
|
|
|
_pingStepIndex = pingIndex * 2 + (secondClick ? 2 : 1);
|
|
|
|
|
|
Debug.Log($"StepManager: Ping步进 -> {_pingStepIndex} (ping{pingIndex} second={secondClick})");
|
2026-07-02 16:22:17 +08:00
|
|
|
|
OnStepChanged?.Invoke(_pingStepIndex);
|
|
|
|
|
|
}
|
2026-07-09 18:28:08 +08:00
|
|
|
|
|
|
|
|
|
|
public void SetPingStepIndex(int index)
|
|
|
|
|
|
{
|
|
|
|
|
|
_pingStepIndex = index;
|
|
|
|
|
|
Debug.Log($"StepManager: Ping彻底重置 -> {index}");
|
|
|
|
|
|
}
|
2026-07-02 16:22:17 +08:00
|
|
|
|
|
2026-07-09 03:16:00 +08:00
|
|
|
|
public void DecrementPingStep()
|
2026-07-02 16:22:17 +08:00
|
|
|
|
{
|
2026-07-09 06:14:48 +08:00
|
|
|
|
_pingStepIndex = Mathf.Max(0, _pingStepIndex - 1);
|
2026-07-09 03:16:00 +08:00
|
|
|
|
Debug.Log($"StepManager: Ping撤销 -> {_pingStepIndex}");
|
2026-07-02 16:22:17 +08:00
|
|
|
|
OnStepChanged?.Invoke(_pingStepIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-09 16:51:57 +08:00
|
|
|
|
public void ResetPingStep()
|
|
|
|
|
|
{
|
|
|
|
|
|
_pingStepIndex = 0;
|
|
|
|
|
|
Debug.Log($"StepManager: Ping彻底重置 -> {_pingStepIndex}");
|
|
|
|
|
|
OnStepChanged?.Invoke(_pingStepIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-09 03:16:00 +08:00
|
|
|
|
public void DecrementWomanStep()
|
2026-07-02 16:22:17 +08:00
|
|
|
|
{
|
2026-07-09 03:16:00 +08:00
|
|
|
|
if (_womanStepIndex > 0) _womanStepIndex--;
|
|
|
|
|
|
Debug.Log($"StepManager: Woman撤销 -> {_womanStepIndex}");
|
|
|
|
|
|
OnStepChanged?.Invoke(_womanStepIndex);
|
2026-07-02 16:22:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-02 16:29:52 +08:00
|
|
|
|
public void PreviousStep()
|
2026-06-24 02:33:48 +08:00
|
|
|
|
{
|
2026-07-08 09:38:42 +08:00
|
|
|
|
Debug.LogError("====== StepManager: 接收到 PreviousStep 指令! ======");
|
|
|
|
|
|
|
|
|
|
|
|
// 如果尝试撤销 3D 交互成功,就不再回退 UI
|
|
|
|
|
|
if (TryUndoActiveHandler())
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("====== StepManager: 成功撤销 3D 交互,不进行常规的 PreviousStep 流程 ======");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (_currentStepIndex > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
GoToStep(_currentStepIndex - 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("====== StepManager: 已经是第一步,无法后退 ======");
|
|
|
|
|
|
}
|
2026-06-24 02:33:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public StepData GetCurrentStep()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_activeSteps == null || _currentStepIndex < 0 || _currentStepIndex >= _activeSteps.Length)
|
|
|
|
|
|
return null;
|
|
|
|
|
|
return _activeSteps[_currentStepIndex];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void OnStepInteractionComplete(float proportion = 1f, string feedback = "")
|
|
|
|
|
|
{
|
|
|
|
|
|
var step = GetCurrentStep();
|
|
|
|
|
|
if (step == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
if (_mode == ExperimentMode.Exam)
|
|
|
|
|
|
{
|
|
|
|
|
|
string fb = string.IsNullOrEmpty(feedback) ? step.ErrorFeedback : feedback;
|
|
|
|
|
|
GameManager.Instance.RecordExamResult(_currentStepIndex, step.ScoreWeight, proportion, fb);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (_mode == ExperimentMode.Learn)
|
|
|
|
|
|
NextStep();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void CompleteExperiment()
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("StepManager: 实验流程结束");
|
|
|
|
|
|
OnExperimentComplete?.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SwitchMode(ExperimentMode newMode)
|
|
|
|
|
|
{
|
|
|
|
|
|
GameManager.Instance.CurrentMode = newMode;
|
|
|
|
|
|
Initialize(GameManager.Instance.CurrentExperimentType, newMode, GameManager.Instance.CurrentFixationMethod);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void SwitchFixation(FixationMethod newFixation)
|
|
|
|
|
|
{
|
|
|
|
|
|
GameManager.Instance.CurrentFixationMethod = newFixation;
|
|
|
|
|
|
Initialize(GameManager.Instance.CurrentExperimentType, GameManager.Instance.CurrentMode, newFixation);
|
|
|
|
|
|
}
|
2026-06-30 14:32:30 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void InitWomanSteps()
|
|
|
|
|
|
{
|
|
|
|
|
|
_womanObject = GameObject.Find("woman");
|
|
|
|
|
|
_touchArrayObject = GameObject.Find("touchArray");
|
2026-06-30 23:07:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 保存初始位置,用于回退到 step 0
|
|
|
|
|
|
if (_womanObject != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_womanInitPos = _womanObject.transform.position;
|
|
|
|
|
|
_womanInitRot = _womanObject.transform.rotation;
|
|
|
|
|
|
Debug.Log($"StepManager: woman初始位置已保存 ({_womanInitPos})");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-30 14:32:30 +08:00
|
|
|
|
var pts = GameObject.Find("womanPointArray");
|
|
|
|
|
|
if (pts != null) { _womanMaxStep = pts.transform.childCount; _womanPositions = new Transform[_womanMaxStep]; for (int i = 0; i < _womanMaxStep; i++) _womanPositions[i] = pts.transform.GetChild(i); }
|
|
|
|
|
|
if (_touchArrayObject != null) { _touchPoints = new GameObject[_touchArrayObject.transform.childCount]; for (int i = 0; i < _touchPoints.Length; i++) _touchPoints[i] = _touchArrayObject.transform.GetChild(i).gameObject; }
|
|
|
|
|
|
_womanStepIndex = 0;
|
|
|
|
|
|
Debug.Log($"StepManager: Woman步进已初始化, 共{_womanMaxStep}个位置");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-02 16:22:17 +08:00
|
|
|
|
public void InitPingSteps()
|
|
|
|
|
|
{
|
|
|
|
|
|
var mi = GameObject.Find("manInjury");
|
|
|
|
|
|
if (mi == null) return;
|
|
|
|
|
|
_pingObjects = new GameObject[4];
|
|
|
|
|
|
_chanraoObjects = new GameObject[4];
|
2026-07-08 09:38:42 +08:00
|
|
|
|
|
|
|
|
|
|
var pings = Object.FindObjectsOfType<PingClickHandler>(true);
|
|
|
|
|
|
foreach (var p in pings)
|
2026-07-02 16:22:17 +08:00
|
|
|
|
{
|
2026-07-08 09:38:42 +08:00
|
|
|
|
if (p.pingIndex >= 0 && p.pingIndex < 4)
|
|
|
|
|
|
{
|
|
|
|
|
|
_pingObjects[p.pingIndex] = p.gameObject;
|
|
|
|
|
|
if (p.chanraoObject != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_chanraoObjects[p.pingIndex] = p.chanraoObject;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-07-02 16:22:17 +08:00
|
|
|
|
}
|
2026-07-08 09:38:42 +08:00
|
|
|
|
|
2026-07-02 16:22:17 +08:00
|
|
|
|
_pingStepIndex = 0;
|
|
|
|
|
|
Debug.Log("StepManager: Ping步进已初始化");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-30 14:32:30 +08:00
|
|
|
|
public void RecordWomanStep(int newStepIndex) { _womanStepIndex = Mathf.Clamp(newStepIndex, 0, _womanMaxStep); Debug.Log($"StepManager: Woman步进 -> {_womanStepIndex}"); OnStepChanged?.Invoke(_womanStepIndex); }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void MoveWomanToStep(int step)
|
|
|
|
|
|
{
|
2026-06-30 23:07:19 +08:00
|
|
|
|
if (_womanObject == null || _womanPositions == null) return;
|
|
|
|
|
|
if (step < 0 || step > _womanPositions.Length) return;
|
|
|
|
|
|
|
|
|
|
|
|
if (step == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 回到初始位置
|
|
|
|
|
|
_womanObject.transform.position = _womanInitPos;
|
|
|
|
|
|
_womanObject.transform.rotation = _womanInitRot;
|
|
|
|
|
|
Debug.Log("StepManager: woman 回到初始位置");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var t = _womanPositions[step - 1];
|
|
|
|
|
|
_womanObject.transform.position = t.position;
|
|
|
|
|
|
_womanObject.transform.rotation = t.rotation;
|
|
|
|
|
|
}
|
2026-06-30 14:32:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void UpdateTouchVisibility(int step)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_touchPoints == null) return;
|
2026-06-30 14:47:51 +08:00
|
|
|
|
for (int i = 0; i < _touchPoints.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool show = (i == step);
|
|
|
|
|
|
_touchPoints[i].SetActive(show);
|
|
|
|
|
|
if (show)
|
|
|
|
|
|
{
|
|
|
|
|
|
var mr = _touchPoints[i].GetComponent<MeshRenderer>();
|
|
|
|
|
|
if (mr != null) mr.enabled = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-06-30 14:32:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Header("=== Woman 步进追踪(不依赖 Config) ===")]
|
|
|
|
|
|
[SerializeField] private GameObject _womanObject;
|
|
|
|
|
|
[SerializeField] private GameObject _touchArrayObject;
|
|
|
|
|
|
|
|
|
|
|
|
private int _womanStepIndex = 0;
|
|
|
|
|
|
private int _womanMaxStep = 3;
|
|
|
|
|
|
private Transform[] _womanPositions;
|
|
|
|
|
|
private GameObject[] _touchPoints;
|
2026-07-02 16:22:17 +08:00
|
|
|
|
private GameObject[] _pingObjects;
|
|
|
|
|
|
private GameObject[] _chanraoObjects;
|
|
|
|
|
|
private int _pingStepIndex = 0;
|
|
|
|
|
|
private int _pingMaxStep = 8; // 4 pings × 2 clicks each
|
2026-06-30 23:07:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Vector3 _womanInitPos;
|
|
|
|
|
|
private Quaternion _womanInitRot;
|
2026-06-24 02:33:48 +08:00
|
|
|
|
}
|