Fix returning to home bug: ensure all pings, chanrao, and Shose are hidden completely

This commit is contained in:
yangbear
2026-07-12 06:59:39 +08:00
parent fb0a77625a
commit cd0944be45
+72 -235
View File
@@ -86,96 +86,47 @@ public class PageController : MonoBehaviour
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 初始化完成 ===");
}
private void Update()
{
#if UNITY_EDITOR
private void OnValidate()
if (!Application.isPlaying)
{
if (Application.isPlaying) return;
UnityEditor.EditorApplication.delayCall += () =>
if (_editorPreview != EditorPreviewPage.None)
{
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;
Page targetPage = (Page)((int)_editorPreview - 1);
ShowPage(targetPage);
}
_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);
if (page == Page.Home) FindObjectOfType<AudioManager>()?.PlayHomeBg();
if (_uiManager != null)
_uiManager.enabled = (page == Page.Experiment);
if (page == Page.Home) FindObjectOfType<AudioManager>()?.PlayHomeBg(); // 背景音乐: 首页播 homeBg, 选固定方式时停, 实验启动时播 experimentBg
if (page == Page.Home) FindObjectOfType<AudioManager>()?.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);
if (page == Page.Home) FindObjectOfType<AudioManager>()?.PlayHomeBg();
if (page == Page.ModeSelect && _modeDescText != null)
_modeDescText.text = "";
Debug.Log($"PageController: 页面切换 -> [{page}]");
}
/// <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);
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
@@ -185,210 +136,88 @@ public class PageController : MonoBehaviour
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;
if (_modeDescText != null)
_modeDescText.text = (mode == ExperimentMode.Learn) ? _practiceModeDesc : _examModeDesc;
GameManager.Instance.CurrentMode = mode;
GameManager.Instance.CurrentExperimentType = ExperimentType.FractureFixation;
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;
}
GameManager.Instance.CurrentFixationMethod = method;
gm.CurrentMode = _selectedMode;
gm.CurrentFixationMethod = method;
Debug.Log($"PageController: GameManager 已设置 Mode=[{gm.CurrentMode}] Fixation=[{gm.CurrentFixationMethod}]");
// 隐藏所有UI面板,准备播放片头动画
FindObjectOfType<AudioManager>()?.StopBgMusic();
FindObjectOfType<AudioManager>()?.StopBgMusic();
HideAllPages();
// 找到 OpeningFlowController 播放片头动画
var openingFlow = FindObjectOfType<OpeningFlowController>();
if (openingFlow != null)
{
Debug.Log("PageController: 开始播放片头动画,ExperimentPanel 将在动画结束后显示");
ShowPage(Page.Experiment);
openingFlow.PlayOpeningFlow(() =>
{
Debug.Log("PageController: 片头动画完成,显示 ExperimentPanel");
ActivateExperimentObjects();
var smW = FindObjectOfType<StepManager>(); if (smW != null) smW.InitWomanSteps(); ShowPage(Page.Experiment);
if (_uiManager != null)
{
_uiManager.gameObject.SetActive(true);
}
var stepManager = FindObjectOfType<StepManager>();
if (stepManager != null)
{
stepManager.InitializeFromGameManager();
}
else
{
Debug.LogWarning("PageController: 未找到 StepManager,实验步骤不会自动初始化");
}
StartCoroutine(StartInitialVoiceAndCameraRoutine());
});
}
else
{
Debug.LogWarning("PageController: 未找到 OpeningFlowController,直接显示 ExperimentPanel");
ShowPage(Page.Experiment);
if (_uiManager != null) _uiManager.gameObject.SetActive(true);
var stepManager = FindObjectOfType<StepManager>();
if (stepManager != null)
{
}
}
}
/// <summary>
/// 激活实验场景物件(medicalBox等),在动画完成后调用
/// </summary>
private void ActivateExperimentObjects()
{
Debug.Log("PageController: [ActivateExperimentObjects] 显示实验物件");
// 强制确保所有 ping/chanrao/chanraotuibu 隐藏
var miClean = GameObject.Find("manInjury");
if (miClean != null)
{
foreach (Transform child in miClean.transform)
{
if (child.name.Contains("ping") || child.name.Contains("chanrao"))
{
child.gameObject.SetActive(false);
Debug.Log("PageController: 强制隐藏 " + child.name);
}
}
}
FindObjectOfType<AudioManager>()?.PlayExperimentBg();
FindObjectOfType<AudioManager>()?.PlayExperimentBg();
var allObjects = FindObjectsOfType<GameObject>(true);
foreach (var go in allObjects)
{
if (go.name == "medicalBox") { go.SetActive(true); Debug.Log("PageController: medicalBox 已显示"); break; }
}
// 隐藏所有的 point1, 2, 3,不要让它们显示出来
var touchArray = GameObject.Find("touchArray");
if (touchArray != null)
{
foreach (Transform child in touchArray.transform)
{
child.gameObject.SetActive(false);
}
}
// 把 woman 直接放到 point1 的位置
var woman = GameObject.Find("woman");
var point1 = GameObject.Find("womanPointArray/point1");
if (woman != null && point1 != null)
{
woman.transform.position = point1.transform.position;
woman.transform.rotation = point1.transform.rotation;
}
// 启动语音、等待及切换摄像机并激活鞋子的流程
if (stepManager != null) stepManager.InitializeFromGameManager();
StartCoroutine(StartInitialVoiceAndCameraRoutine());
}
}
var tipPanel = GameObject.Find("TipPanel");
if (tipPanel != null) tipPanel.SetActive(true);
var dialogue = GameObject.Find("DialogueBubble");
if (dialogue != null) dialogue.SetActive(true);
private void OnExperimentBackClicked()
{
ReturnToHome();
}
public void ReturnToHome()
{
Debug.Log("PageController: [ReturnToHome] 返回首页并重置场景");
Debug.Log("PageController: 返回首页");
HideShose();
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);
// 隐藏所有 ping/chanrao/chanraotuibu
var mi = GameObject.Find("manInjury");
if (mi != null) {
foreach (Transform child in mi.transform) {
if (child.name.Contains("ping") || child.name.Contains("chanrao"))
child.gameObject.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 cam3Go = GameObject.Find("camera3");
if (cam3Go != null) { var c = cam3Go.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); }
// 重置 woman 动画
if (woman != null)
if (manInjury != null)
{
var wAnim = woman.GetComponent<Animator>();
if (wAnim != null)
foreach (var handler in manInjury.GetComponentsInChildren<PingClickHandler>(true))
{
wAnim.SetBool("isCrouch", false);
wAnim.Play("Idle", 0, 0f); // 假设其默认闲置动画为 Idle 或类似名称
handler.ResetState();
handler.gameObject.SetActive(false); // 强制隐藏 ping
}
foreach (var handler in manInjury.GetComponentsInChildren<ChanraoTuibuHandler>(true))
{
handler.ResetState();
handler.gameObject.SetActive(false); // 强制隐藏 chanraotuibu
}
// 这里也可以顺带隐藏所有的 man_ba_zi_chan_rao 下的 chanrao
}
// 重置 manInjury 动画
if (mi != null)
{
var mAnim = mi.GetComponent<Animator>();
if (mAnim != null)
{
mAnim.SetBool("CheckFoot", false);
mAnim.Play("manInjury", 0, 0f); // 默认动画
}
// 重置所有的 Handler 状态
foreach (var handler in mi.GetComponentsInChildren<PingClickHandler>(true)) handler.ResetState();
foreach (var handler in mi.GetComponentsInChildren<ChanraoTuibuHandler>(true)) handler.ResetState();
}
// 找到 Shose 重置点击状态
// 找到 Shose 重置并彻底隐藏
var shose = GameObject.Find("Shose");
if (shose == null)
{
@@ -399,8 +228,23 @@ public class PageController : MonoBehaviour
{
var h = shose.GetComponent<ShoseClickHandler>();
if (h != null) h.ResetState();
// 关键:返回主页时,必须禁用点击组件,并隐藏物体
if (h != null) h.enabled = false;
shose.SetActive(false);
}
// 把 touchArray 里的点也关掉
var touchArray = GameObject.Find("touchArray");
if (touchArray != null)
{
foreach (Transform t in touchArray.transform)
{
t.gameObject.SetActive(false);
}
}
// ------------------------------------------------
ShowPage(Page.Home);
}
@@ -409,7 +253,7 @@ public class PageController : MonoBehaviour
float waitTime = 1f; // 默认等1秒
var am = FindObjectOfType<AudioManager>();
// --- 新增:强制隐藏视频面板 ---
// 隐藏视频面板
var allT = Resources.FindObjectsOfTypeAll<Transform>();
foreach (var t in allT)
{
@@ -418,14 +262,12 @@ public class PageController : MonoBehaviour
t.gameObject.SetActive(false);
}
}
// ------------------------------
// 实验刚开始,立刻激活point2,不等语音播完
// 找鞋子
var shose = GameObject.Find("Shose");
if (shose == null)
{
var allTransforms = Resources.FindObjectsOfTypeAll<Transform>();
foreach(var t in allTransforms) { if (t.parent == null && t.name == "Shose") { shose = t.gameObject; break; } }
foreach(var t in allT) { if (t.parent == null && t.name == "Shose") { shose = t.gameObject; break; } }
}
var point2 = GameObject.Find("touchArray/point2");
@@ -445,16 +287,17 @@ public class PageController : MonoBehaviour
if (h == null) h = shose.AddComponent<ShoseClickHandler>();
h.targetPoint = GameObject.Find("ShosePoint")?.transform;
// 强制将鞋子点击后的下一步指向 ping.004
// 这里因为你换了绑带模型:我们需要确保拿到正确的 ping.004
// 只要场景里激活/存在叫 ping.004 的就行
var ping004 = GameObject.Find("ping.004");
if (ping004 == null)
{
var mi = GameObject.Find("manInjury");
if (mi != null) ping004 = mi.transform.Find("ping.004")?.gameObject;
// 如果是隐藏状态,用全局查找
foreach(var t in allT) { if (t.name == "ping.004") { ping004 = t.gameObject; break; } }
}
h.nextObject = ping004;
// 确保一开始鞋子模型可见,但不闪烁且不可点击
// 鞋子出现,但默认不开组件(不可点击
h.enabled = false;
shose.SetActive(true);
}
@@ -471,7 +314,7 @@ public class PageController : MonoBehaviour
point2.SetActive(false);
}
// 1. 强制播放第一句语音:“周围环境安全,我是救护志愿者,我可以帮助您吗”
// 1. 强制播放第一句语音
if (am != null)
{
#if UNITY_EDITOR
@@ -486,23 +329,18 @@ public class PageController : MonoBehaviour
Debug.Log($"PageController: 开始等待 {waitTime} 秒以切换摄像机并激活鞋子");
// --- 开场动画结束,开始显示 TipPanel,直到切换到 camera2 再由切换逻辑隐藏 ---
var tipPanel = GameObject.Find("TipPanel");
if (tipPanel == null)
{
var allTips = Resources.FindObjectsOfTypeAll<Transform>();
foreach(var t in allTips) { if (t.name == "TipPanel") { tipPanel = t.gameObject; break; } }
foreach(var t in allT) { if (t.name == "TipPanel") { tipPanel = t.gameObject; break; } }
}
if (tipPanel != null) tipPanel.SetActive(true);
// ---------------------------------------------------------------------
yield return new WaitForSeconds(waitTime);
// 2. 切换到 camera3
if (tipPanel != null) tipPanel.SetActive(false);
if (am != null) am.SwitchToCamera3();
// 3. 切换相机后,显示 point2
if (point2 != null)
{
point2.SetActive(true);
@@ -521,5 +359,4 @@ public class PageController : MonoBehaviour
#endregion
}
}