Files
VFSUnity/Assets/Scripts/UI/PageController.cs
T

406 lines
16 KiB
C#
Raw Normal View History

using UnityEngine;
using UnityEngine.UI;
public class PageController : MonoBehaviour
{
[Header("=== 三个主页面 ===")]
[SerializeField] private GameObject _homePagePanel;
[SerializeField] private GameObject _modeSelectPanel;
[SerializeField] private GameObject _fixationPanel;
[Header("=== 实验页面 ===")]
[SerializeField] private GameObject _experimentPanel;
[SerializeField] private Button _btnExperimentBack;
[Header("=== 实验内 UI(由 UIManager 管理)===")]
[SerializeField] private UIManager _uiManager;
[Header("=== 首页控件 ===")]
[SerializeField] private Button _btnStart;
[SerializeField] private Button _btnExit;
[Header("=== 模式选择页控件 ===")]
[SerializeField] private Button _btnBack;
[SerializeField] private Button _btnPracticeMode;
[SerializeField] private Button _btnExamMode;
[SerializeField] private Text _modeDescText;
[Header("=== 固定方式选择页控件 ===")]
[SerializeField] private Button _btnFixationBack;
[SerializeField] private Button _btnLimbFixation;
[SerializeField] private Button _btnSplintFixation;
[Header("=== 模式说明文案 ===")]
[SerializeField] [TextArea(2, 4)] private string _practiceModeDesc =
"模拟练习模式:不限时长,可反复练习。系统不评分,帮助您熟悉实验流程和操作步骤。";
[SerializeField] [TextArea(2, 4)] private string _examModeDesc =
"考核评估模式:限定时间,完成后系统自动评分,并提供详细反馈报告。";
[Header("=== 编辑器预览(仅 Editor 模式有效)===")]
[SerializeField] private EditorPreviewPage _editorPreview = EditorPreviewPage.None;
public enum Page { Home, ModeSelect, Fixation, Experiment }
public enum EditorPreviewPage { None, Home, ModeSelect, Fixation, Experiment }
private Page _currentPage = Page.Home;
private ExperimentMode _selectedMode = ExperimentMode.Learn;
private void Start()
{
Debug.Log("=== PageController 初始化开始 ===");
// 背景音乐 AudioSource
_bgAudioSource = gameObject.AddComponent<AudioSource>();
_bgAudioSource.loop = true;
_bgAudioSource.playOnAwake = false;
// 绑定首页按钮
if (_btnStart != null) { _btnStart.onClick.AddListener(OnStartClicked); Debug.Log("PageController: _btnStart 绑定成功"); }
else Debug.LogError("PageController: _btnStart 未赋值!");
if (_btnExit != null) { _btnExit.onClick.AddListener(OnExitClicked); Debug.Log("PageController: _btnExit 绑定成功"); }
else Debug.LogError("PageController: _btnExit 未赋值!");
if (_btnBack != null) { _btnBack.onClick.AddListener(OnModeBackClicked); Debug.Log("PageController: _btnBack 绑定成功"); }
else Debug.LogError("PageController: _btnBack 未赋值!");
if (_btnPracticeMode != null) { _btnPracticeMode.onClick.AddListener(() => OnModeSelected(ExperimentMode.Learn)); Debug.Log("PageController: _btnPracticeMode 绑定成功"); }
else Debug.LogError("PageController: _btnPracticeMode 未赋值!");
if (_btnExamMode != null) { _btnExamMode.onClick.AddListener(() => OnModeSelected(ExperimentMode.Exam)); Debug.Log("PageController: _btnExamMode 绑定成功"); }
else Debug.LogError("PageController: _btnExamMode 未赋值!");
if (_btnFixationBack == null && _fixationPanel != null) { var fb = _fixationPanel.transform.Find("BtnBack"); if (fb != null) { _btnFixationBack = fb.GetComponent<Button>(); Debug.Log("PageController: 自动绑定 FixationPanel/BtnBack"); } }
if (_btnFixationBack != null) { _btnFixationBack.onClick.AddListener(OnFixationBackClicked); Debug.Log("PageController: _btnFixationBack 绑定成功"); }
else Debug.LogError("PageController: _btnFixationBack 未找到!");
if (_btnLimbFixation != null) { _btnLimbFixation.onClick.AddListener(() => OnFixationSelected(FixationMethod.LimbFixation)); Debug.Log("PageController: _btnLimbFixation 绑定成功"); }
else Debug.LogError("PageController: _btnLimbFixation 未赋值!");
if (_btnSplintFixation != null) { _btnSplintFixation.onClick.AddListener(() => OnFixationSelected(FixationMethod.SplintFixation)); Debug.Log("PageController: _btnSplintFixation 绑定成功"); }
else Debug.LogError("PageController: _btnSplintFixation 未赋值!");
if (_btnExperimentBack == null && _experimentPanel != null) { var eb = _experimentPanel.transform.Find("Navbar/BtnBack"); if (eb != null) { _btnExperimentBack = eb.GetComponent<Button>(); Debug.Log("PageController: 自动绑定 ExperimentPanel/Navbar/BtnBack"); } }
if (_btnExperimentBack != null) { _btnExperimentBack.onClick.AddListener(OnExperimentBackClicked); Debug.Log("PageController: _btnExperimentBack 绑定成功"); }
else Debug.LogError("PageController: _btnExperimentBack 未找到!");
if (_modeDescText != null) { _modeDescText.text = _practiceModeDesc + "\n\n" + _examModeDesc; }
ShowPage(Page.Home);
Debug.Log("=== PageController 初始化完成 ===");
}
#if UNITY_EDITOR
private void OnValidate()
{
if (Application.isPlaying) return;
UnityEditor.EditorApplication.delayCall += () =>
{
if (this == null) return;
if (Application.isPlaying) return;
switch (_editorPreview)
{
case EditorPreviewPage.None: break;
case EditorPreviewPage.Home: ShowPageEditMode(Page.Home); break;
case EditorPreviewPage.ModeSelect: ShowPageEditMode(Page.ModeSelect); break;
case EditorPreviewPage.Fixation: ShowPageEditMode(Page.Fixation); break;
case EditorPreviewPage.Experiment: ShowPageEditMode(Page.Experiment); break;
}
_editorPreview = EditorPreviewPage.None;
};
}
private void ShowPageEditMode(Page page)
{
if (_homePagePanel != null) _homePagePanel.SetActive(page == Page.Home);
if (_modeSelectPanel != null) _modeSelectPanel.SetActive(page == Page.ModeSelect);
if (_fixationPanel != null) _fixationPanel.SetActive(page == Page.Fixation);
if (_experimentPanel != null) _experimentPanel.SetActive(page == Page.Experiment);
if (_uiManager != null)
_uiManager.enabled = (page == Page.Experiment);
// 背景音乐: 首页播 homeBg, 选固定方式时停, 实验启动时播 experimentBg
if (page == Page.Home) PlayHomeBg();
Debug.Log($"PageController(编辑器预览): 切换到 [{page}]");
}
#endif
#region 页面切换
private void ShowPage(Page page)
{
Debug.Log($"PageController: 页面切换 [{_currentPage}] → [{page}]");
_currentPage = page;
if (_homePagePanel != null) _homePagePanel.SetActive(page == Page.Home);
if (_modeSelectPanel != null) _modeSelectPanel.SetActive(page == Page.ModeSelect);
if (_fixationPanel != null) _fixationPanel.SetActive(page == Page.Fixation);
if (_experimentPanel != null) _experimentPanel.SetActive(page == Page.Experiment);
if (_uiManager != null) _uiManager.enabled = (page == Page.Experiment);
// 背景音乐: 首页播 homeBg, 选固定方式时停, 实验启动时播 experimentBg
if (page == Page.Home) PlayHomeBg();
// 背景音乐控制
if (page == Page.Home) PlayHomeBg();
else if (page != Page.Experiment) StopBgMusic();
}
private void PlayHomeBg()
{
if (_homeBgClip != null && _bgAudioSource != null && _bgAudioSource.clip != _homeBgClip)
{
_bgAudioSource.clip = _homeBgClip;
_bgAudioSource.Play();
Debug.Log("PageController: 播放首页背景音乐");
}
}
private void StopBgMusic()
{
if (_bgAudioSource != null && _bgAudioSource.isPlaying)
{
_bgAudioSource.Stop();
Debug.Log("PageController: 停止背景音乐");
}
}
private void PlayExperimentBg()
{
StopBgMusic();
if (_experimentBgClip != null && _bgAudioSource != null)
{
_bgAudioSource.clip = _experimentBgClip;
_bgAudioSource.Play();
Debug.Log("PageController: 播放实验背景音乐");
}
}
/// <summary>
/// 隐藏所有页面,用于播放片头动画时清空 UI
/// </summary>
private void HideAllPages()
{
Debug.Log("PageController: [HideAllPages] 隐藏所有 UI 面板");
if (_homePagePanel != null) _homePagePanel.SetActive(false);
if (_modeSelectPanel != null) _modeSelectPanel.SetActive(false);
if (_fixationPanel != null) _fixationPanel.SetActive(false);
if (_experimentPanel != null) _experimentPanel.SetActive(false);
2026-06-30 01:22:54 +08:00
var tipPanel = GameObject.Find("TipPanel");
if (tipPanel != null) tipPanel.SetActive(false);
var dialogue = GameObject.Find("DialogueBubble");
if (dialogue != null) dialogue.SetActive(false);
}
#endregion
#region 按钮回调
private void OnStartClicked()
{
Debug.Log("PageController: [BtnStart] 点击 -> 切换到 ModeSelect");
ShowPage(Page.ModeSelect);
}
private void OnExitClicked()
{
Debug.Log("PageController: [BtnExit] 点击 -> 退出应用");
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
private void OnModeBackClicked()
{
Debug.Log("PageController: [BtnBack(Mode)] 点击 -> 返回 Home");
ShowPage(Page.Home);
}
private void OnModeSelected(ExperimentMode mode)
{
Debug.Log($"PageController: [ModeSelected] 点击 -> 模式 [{mode}] -> 切换到 Fixation");
_selectedMode = mode;
ShowPage(Page.Fixation);
}
private void OnFixationBackClicked()
{
Debug.Log("PageController: [BtnFixationBack] 点击 -> 返回 ModeSelect");
if (_modeDescText != null)
{
_modeDescText.text = _practiceModeDesc + "\n\n" + _examModeDesc;
}
ShowPage(Page.ModeSelect);
}
private void OnExperimentBackClicked()
{
Debug.Log("PageController: [BtnExperimentBack] 点击 -> 返回 Fixation");
ShowPage(Page.Fixation);
}
private void OnFixationSelected(FixationMethod method)
{
Debug.Log($"PageController: [FixationSelected] 点击 -> 固定方式 [{method}]");
var gm = GameManager.Instance;
if (gm == null)
{
Debug.LogError("PageController: GameManager.Instance 为空!");
return;
}
gm.CurrentMode = _selectedMode;
gm.CurrentFixationMethod = method;
Debug.Log($"PageController: GameManager 已设置 Mode=[{gm.CurrentMode}] Fixation=[{gm.CurrentFixationMethod}]");
// 隐藏所有UI面板,准备播放片头动画
StopBgMusic(); HideAllPages();
// 找到 OpeningFlowController 播放片头动画
var openingFlow = FindObjectOfType<OpeningFlowController>();
if (openingFlow != null)
{
Debug.Log("PageController: 开始播放片头动画,ExperimentPanel 将在动画结束后显示");
openingFlow.PlayOpeningFlow(() =>
{
Debug.Log("PageController: 片头动画完成,显示 ExperimentPanel");
ActivateExperimentObjects();
var smW = FindObjectOfType<StepManager>(); if (smW != null) smW.InitWomanSteps(); ShowPage(Page.Experiment);
var stepManager = FindObjectOfType<StepManager>();
if (stepManager != null)
{
}
else
{
Debug.LogWarning("PageController: 未找到 StepManager,实验步骤不会自动初始化");
}
});
}
else
{
Debug.LogWarning("PageController: 未找到 OpeningFlowController,直接显示 ExperimentPanel");
ShowPage(Page.Experiment);
var stepManager = FindObjectOfType<StepManager>();
if (stepManager != null)
{
}
}
}
/// <summary>
/// 激活实验场景物件(medicalBox等),在动画完成后调用
/// </summary>
private void ActivateExperimentObjects()
{
Debug.Log("PageController: [ActivateExperimentObjects] 显示实验物件");
PlayExperimentBg();
var allObjects = FindObjectsOfType<GameObject>(true);
foreach (var go in allObjects)
{
if (go.name == "medicalBox") { go.SetActive(true); Debug.Log("PageController: medicalBox 已显示"); break; }
}
var touch = GameObject.Find("touchArray");
if (touch != null && touch.transform.childCount > 0) { touch.transform.GetChild(0).gameObject.SetActive(true); Debug.Log("PageController: touchArray/point1 已显示"); }
var tipPanel = GameObject.Find("TipPanel");
if (tipPanel != null) tipPanel.SetActive(true);
var dialogue = GameObject.Find("DialogueBubble");
if (dialogue != null) dialogue.SetActive(true);
}
private System.Collections.IEnumerator PlayWomanAudioSequence()
{
if (_womanClips == null || _womanClips.Length == 0) yield break;
var voiceSource = gameObject.AddComponent<AudioSource>();
voiceSource.loop = false;
voiceSource.playOnAwake = false;
foreach (var clip in _womanClips)
{
if (clip == null) continue;
voiceSource.clip = clip;
voiceSource.Play();
Debug.Log($"PageController: 播放woman语音: {clip.name}");
yield return new WaitForSeconds(clip.length + 0.5f);
}
}
public void ReturnToHome()
{
Debug.Log("PageController: [ReturnToHome] 返回首页并重置场景");
var man = GameObject.Find("man");
if (man != null) man.SetActive(true);
var man2 = GameObject.Find("man2");
if (man2 != null) man2.SetActive(true);
var woman = GameObject.Find("woman");
if (woman != null) woman.SetActive(false);
var manInjury = GameObject.Find("manInjury");
if (manInjury != null) manInjury.SetActive(false);
var medicalBox = GameObject.Find("medicalBox");
if (medicalBox != null) medicalBox.SetActive(false);
// 用名字找主摄像机(Camera.main 在禁用后返回 null
var mainGo = GameObject.Find("Main Camera");
if (mainGo != null) { var c = mainGo.GetComponent<Camera>(); if (c != null) c.enabled = true; }
var cam2Go = GameObject.Find("camera2");
if (cam2Go != null) { var c = cam2Go.GetComponent<Camera>(); if (c != null) c.enabled = false; }
var manAnim = man != null ? man.GetComponent<Animator>() : null;
if (manAnim != null) { manAnim.SetBool("IsStart", false); manAnim.SetBool("IsFull", false); manAnim.Play("manIdle", 0, 0f); }
ShowPage(Page.Home);
}
#endregion
[Header("=== 音频 ===")]
[SerializeField] private AudioClip _homeBgClip;
[SerializeField] private AudioClip _experimentBgClip;
[SerializeField] private AudioClip[] _womanClips;
private AudioSource _bgAudioSource;
}
private void PlayHomeBg()
{
if (_bgAudioSource == null) _bgAudioSource = gameObject.AddComponent<AudioSource>();
_bgAudioSource.loop = true;
_bgAudioSource.playOnAwake = false;
if (_homeBgClip != null && _bgAudioSource.clip != _homeBgClip)
{
_bgAudioSource.clip = _homeBgClip;
_bgAudioSource.Play();
Debug.Log("PageController: 播放首页背景音乐");
}
}
private void StopBgMusic()
{
if (_bgAudioSource != null && _bgAudioSource.isPlaying) { _bgAudioSource.Stop(); Debug.Log("PageController: 停止背景音乐"); }
}
private void PlayExperimentBg()
{
StopBgMusic();
if (_bgAudioSource == null) _bgAudioSource = gameObject.AddComponent<AudioSource>();
_bgAudioSource.loop = true;
_bgAudioSource.playOnAwake = false;
if (_experimentBgClip != null) { _bgAudioSource.clip = _experimentBgClip; _bgAudioSource.Play(); Debug.Log("PageController: 播放实验背景音乐"); }
}