GameObject.Find 使用技巧

GameObject.Find是全局搜索

 

如果你已经知道这个元件在哪个元件里面的话,且担心场景中有重名元件,可以这样写

GameObject.Find ("Canvas/Panel/Image/Button_FileSvr")

 

using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; public class NPC2 : MonoBehaviour { public GameObject image; public GameObject image1; public GameObject image2; public TextMeshProUGUI text; [Header("按钮设置")] public Button mainMenuButton; public Button startButton; public Button loseButton; public Button winButton; void Start() { // 初始化时隐藏所有按钮 if (mainMenuButton != null) mainMenuButton.gameObject.SetActive(false); if (startButton != null) startButton.gameObject.SetActive(false); if (loseButton != null) loseButton.gameObject.SetActive(false); if (winButton != null) winButton.gameObject.SetActive(false); // 确保UI元素正确隐藏 if (image != null) image.SetActive(false); if (image1 != null) image1.SetActive(false); if (image2 != null) image2.SetActive(false); if (text != null) text.gameObject.SetActive(false); // 将按钮引用传递给DialogueManager if (DialogueManager.Instance != null) { DialogueManager.Instance.startButton = startButton; DialogueManager.Instance.loseButton = loseButton; DialogueManager.Instance.winButton = winButton; DialogueManager.Instance.image = image; DialogueManager.Instance.image1 = image1; DialogueManager.Instance.image2 = image2; DialogueManager.Instance.text = text; } else { Debug.LogError("DialogueManager实例未找到!"); } } void OnTriggerStay2D(Collider2D other) { if (other.CompareTag("Player") && Input.GetKeyDown(KeyCode.F)) { Debug.Log("玩家触发NPC对话"); // 激活UI元素 if (image != null) image.SetActive(true); if (image1 != null) image1.SetActive(true); if (image2 != null) image2.SetActive(true); if (text != null) text.gameObject.SetActive(true); // 启动对话 - 检查DialogueManager是否初始化完成 if (DialogueManager.Instance != null && DialogueManager.Instance.IsInitialized) { DialogueManager.Instance.StartStateDialogue(); // 根据状态显示对应按钮 switch (DialogueManager.Instance.currentState) { case DialogueManager.DialogueState.Before: if (startButton != null) { startButton.gameObject.SetActive(true); // 设置当前选中的按钮 EventSystem.current.SetSelectedGameObject(startButton.gameObject); } break; case DialogueManager.DialogueState.Win: if (winButton != null) { winButton.gameObject.SetActive(true); EventSystem.current.SetSelectedGameObject(winButton.gameObject); } break; case DialogueManager.DialogueState.Lost: if (loseButton != null) { loseButton.gameObject.SetActive(true); EventSystem.current.SetSelectedGameObject(loseButton.gameObject); } break; } } else { Debug.LogWarning("DialogueManager尚未初始化完成,无法启动对话"); } } } } using System.Collections.Generic; using UnityEngine; using TMPro; using System.Collections; using UnityEngine.UI; using UnityEngine.SceneManagement; using UnityEngine.EventSystems; public class DialogueManager : MonoBehaviour { public enum DialogueState { Before, Win, Lost } public static DialogueManager Instance; [Header("UI Elements")] public TextMeshProUGUI tmpText; public float typingSpeed = 0.05f; public TMP_FontAsset fallbackFont; // 备用字体 [Header("Dialogue Content")] public List<string> beforeBattleDialogues = new List<string>(); public List<string> winDialogues = new List<string>(); public List<string> lostDialogues = new List<string>(); [Header("场景布置")] public GameObject image; public GameObject image1; public GameObject image2; public TextMeshProUGUI text; [Header("按钮设置")] public Button startButton; public Button loseButton; public Button winButton; [Header("UI 元素路径")] public string tmpTextPath = "Canvas/DialoguePanel/TMPText"; public string startButtonPath = "Canvas/Buttons/StartButton"; public string winButtonPath = "Canvas/Buttons/WinButton"; public string loseButtonPath = "Canvas/Buttons/LoseButton"; public string imagePath = "Canvas/Background"; private bool isTyping = false; private Coroutine typingCoroutine; private string currentSentence; public DialogueState currentState = DialogueState.Before; public int currentDialogueIndex = 0; private List<string> currentDialogueList; // 添加初始化完成标志 public bool IsInitialized { get; private set; } = false; void Awake() { // 单例模式实现 if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); SceneManager.sceneLoaded += OnSceneLoaded; Debug.Log("对话管理器初始化完成"); } else { Destroy(gameObject); return; } } void Start() { // 初始状态加载 LoadInitialState(); } void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void LoadInitialState() { // 确保对话列表初始化 InitializeDialogueLists(); Debug.Log("加载初始对话状态..."); // 检查存档中的对话状态 if (SaveSystem.Instance != null && SaveSystem.Instance.SaveExists()) { DialogueState savedState = SaveSystem.Instance.GetDialogueState(); int savedIndex = SaveSystem.Instance.GetDialogueIndex(); // 使用SetDialogueState确保正确初始化 SetDialogueState(savedState); currentDialogueIndex = savedIndex; Debug.Log($"从存档加载对话状态: {savedState} 索引: {savedIndex}"); } else { // 检查战斗结果 int result = PlayerPrefs.GetInt("LastBattleResult", -1); // 使用状态设置方法确保列表初始化 if (result == 1) SetDialogueState(DialogueState.Win); else if (result == 0) SetDialogueState(DialogueState.Lost); else SetDialogueState(DialogueState.Before); } // 清除状态 PlayerPrefs.DeleteKey("LastBattleResult"); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { StartCoroutine(DelayedUIFix()); } private IEnumerator DelayedUIFix() { yield return new WaitForEndOfFrame(); EnsureSingleEventSystem(); FixButtonLayer(); yield return StartCoroutine(RebindAfterSceneLoad()); Debug.Log("UI系统修复完成"); IsInitialized = true; // 设置初始化完成标志 } private IEnumerator RebindAfterSceneLoad() { yield return new WaitForEndOfFrame(); // 等待UI渲染完成 // 重新获取按钮引用 startButton = GameObject.Find(startButtonPath)?.GetComponent<Button>(); winButton = GameObject.Find(winButtonPath)?.GetComponent<Button>(); loseButton = GameObject.Find(loseButtonPath)?.GetComponent<Button>(); if (startButton != null) { // 清除旧监听器 startButton.onClick.RemoveAllListeners(); // 添加带调试的新监听 startButton.onClick.AddListener(() => { Debug.Log($"按钮点击时间: {Time.time}"); OnStartClick(); }); // 添加视觉反馈 startButton.onClick.AddListener(() => startButton.image.color = Color.green); } } void Update() { if (tmpText == null) { Debug.LogWarning("tmpText引用为空!"); return; } // 添加跳过功能:按E键跳过当前打字效果 if (Input.GetKeyDown(KeyCode.E) && isTyping) { SkipTyping(); } // 按E键继续下一句对话 else if (Input.GetKeyDown(KeyCode.E) && !isTyping && tmpText.gameObject.activeSelf) { NextSentence(); } if (Input.GetMouseButtonDown(0)) { // 输出当前选中的UI元素 Debug.Log($"当前选中: {EventSystem.current.currentSelectedGameObject?.name}"); // 射线检测调试 PointerEventData eventData = new PointerEventData(EventSystem.current); eventData.position = Input.mousePosition; List<RaycastResult> results = new List<RaycastResult>(); EventSystem.current.RaycastAll(eventData, results); foreach (var result in results) { Debug.Log($"射线命中: {result.gameObject.name}"); } } } // 设置当前对话状态 public void SetDialogueState(DialogueState newState) { currentState = newState; currentDialogueIndex = 0; switch (newState) { case DialogueState.Before: currentDialogueList = beforeBattleDialogues; break; case DialogueState.Win: currentDialogueList = winDialogues; break; case DialogueState.Lost: currentDialogueList = lostDialogues; break; } Debug.Log($"状态已切换至: {newState}"); // 保存状态 SaveDialogueState(); } // 保存对话状态 private void SaveDialogueState() { if (SaveSystem.Instance != null) { SaveSystem.Instance.SaveDialogueState(currentState, currentDialogueIndex); } } private void InitializeDialogueLists() { // 确保所有对话列表都已初始化 if (beforeBattleDialogues == null) beforeBattleDialogues = new List<string>(); if (winDialogues == null) winDialogues = new List<string>(); if (lostDialogues == null) lostDialogues = new List<string>(); // 添加默认对话防止空列表 if (beforeBattleDialogues.Count == 0) beforeBattleDialogues.Add("默认对话:请添加战斗前对话内容"); if (winDialogues.Count == 0) winDialogues.Add("默认对话:请添加胜利后对话内容"); if (lostDialogues.Count == 0) lostDialogues.Add("默认对话:请添加失败后对话内容"); } // 启动当前状态的对话 public void StartStateDialogue() { if (currentDialogueList == null || currentDialogueList.Count == 0) { Debug.LogWarning($"当前对话列表为空! 状态: {currentState}"); // 自动恢复默认列表 SetDialogueState(currentState); } // 确保索引在有效范围内 currentDialogueIndex = Mathf.Clamp(currentDialogueIndex, 0, currentDialogueList.Count - 1); currentSentence = currentDialogueList[currentDialogueIndex]; Debug.Log($"开始对话: {currentSentence}"); // 暂停玩家移动 playercontrol player = FindObjectOfType<playercontrol>(); if (player != null) player.canMove = false; // 锁定玩家输入 Cursor.lockState = CursorLockMode.None; Cursor.visible = true; // 显示对话框UI tmpText.gameObject.SetActive(true); // 在修复按钮层级前,确保按钮引用不为空 if (startButton == null) { // 尝试重新获取按钮引用 startButton = GameObject.Find(startButtonPath)?.GetComponent<Button>(); } FixButtonLayer(); // 确保在最前层 // 启动打字效果协程 if (isTyping) { StopCoroutine(typingCoroutine); } typingCoroutine = StartCoroutine(TypeSentence(currentSentence)); } // 确保对话框在最前层 private void FixButtonLayer() { // 确保按钮在最高层级 if (startButton != null && startButton.transform != null) { Canvas parentCanvas = startButton.GetComponentInParent<Canvas>(); if (parentCanvas != null) { parentCanvas.sortingOrder = 100; startButton.transform.SetAsLastSibling(); } } else { // 如果startButton为空,尝试重新获取 startButton = GameObject.Find(startButtonPath)?.GetComponent<Button>(); if (startButton == null) { Debug.LogWarning("FixButtonLayer: startButton引用为空,无法修复层级。"); } } // 禁用背景图射线检测 if (image != null) { Image bgImage = image.GetComponent<Image>(); if (bgImage != null) { bgImage.raycastTarget = false; // 关键修复[^2] } } } // 显示下一句对话 public void NextSentence() { currentDialogueIndex++; if (currentDialogueIndex < currentDialogueList.Count) { StartStateDialogue(); // 保存当前进度 SaveDialogueState(); } else { // 对话结束 EndDialogue(); } } IEnumerator TypeSentence(string sentence) { isTyping = true; tmpText.text = ""; // 确保文本颜色可见 tmpText.color = new Color(tmpText.color.r, tmpText.color.g, tmpText.color.b, 1f); // 逐字显示 foreach (char letter in sentence.ToCharArray()) { tmpText.text += letter; yield return new WaitForSeconds(typingSpeed); } isTyping = false; } // 跳过当前打字效果 public void SkipTyping() { if (isTyping && typingCoroutine != null) { StopCoroutine(typingCoroutine); tmpText.text = currentSentence; isTyping = false; } } public void EndDialogue() { Debug.Log("对话结束"); if (isTyping && typingCoroutine != null) { StopCoroutine(typingCoroutine); isTyping = false; } // 恢复玩家控制 playercontrol player = FindObjectOfType<playercontrol>(); if (player != null) player.canMove = true; // 隐藏对话框 if (tmpText != null) { tmpText.gameObject.SetActive(false); } // 根据状态显示对应按钮 switch (currentState) { case DialogueState.Before: if (startButton != null) { startButton.gameObject.SetActive(true); EventSystem.current.SetSelectedGameObject(startButton.gameObject); } break; case DialogueState.Win: if (winButton != null) { winButton.gameObject.SetActive(true); EventSystem.current.SetSelectedGameObject(winButton.gameObject); } break; case DialogueState.Lost: if (loseButton != null) { loseButton.gameObject.SetActive(true); EventSystem.current.SetSelectedGameObject(loseButton.gameObject); } break; } // 确保事件系统可用 EnsureSingleEventSystem(); // 保存完成状态 SaveDialogueState(); } private void EnsureSingleEventSystem() { EventSystem[] systems = FindObjectsOfType<EventSystem>(); if (systems.Length > 1) { // 保留第一个销毁其他 for (int i = 1; i < systems.Length; i++) { Destroy(systems[i].gameObject); } } // 创建新事件系统(如果不存在) if (EventSystem.current == null) { GameObject es = new GameObject("EventSystem"); es.AddComponent<EventSystem>(); es.AddComponent<StandaloneInputModule>(); DontDestroyOnLoad(es); } } public void OnMainMenuClick() { Debug.Log("主菜单按钮点击"); SceneManager.LoadScene("MainMenu"); } public void OnStartClick() { if (startButton != null) { startButton.image.color = Color.green; // 视觉反馈 } Debug.Log("场景加载启动"); SceneManager.LoadScene("Fight"); } public void OnLoseClick() { Debug.Log("失败按钮点击"); SceneManager.LoadScene("Fight"); } public void OnWinClick() { if (currentState != DialogueState.Win) { Debug.LogWarning("尝试在非胜利状态执行胜利逻辑"); return; } playercontrol player = FindObjectOfType<playercontrol>(); if (player != null) player.canMove = true; Debug.Log("执行胜利逻辑"); if (image != null) image.SetActive(false); if (image1 != null) image1.SetActive(false); if (image2 != null) image2.SetActive(false); if (text != null) text.gameObject.SetActive(false); if (tmpText != null) tmpText.gameObject.SetActive(false); if (winButton != null) winButton.gameObject.SetActive(false); // 清除对话存档 if (SaveSystem.Instance != null) { SaveSystem.Instance.SaveDialogueState(DialogueState.Before, 0); } } } 为什么我的startbutton不能实现跳转Fight sence的功能,不要改其他功能
08-09
using System.Collections.Generic; using UnityEngine; using TMPro; using System.Collections; using UnityEngine.UI; using UnityEngine.SceneManagement; using UnityEngine.EventSystems; public class DialogueManager : MonoBehaviour { public enum DialogueState { Before, Win, Lost } public static DialogueManager Instance; [Header("UI Elements")] public TextMeshProUGUI tmpText; public float typingSpeed = 0.05f; public TMP_FontAsset fallbackFont; // 备用字体 [Header("Dialogue Content")] public List<string> beforeBattleDialogues = new List<string>(); public List<string> winDialogues = new List<string>(); public List<string> lostDialogues = new List<string>(); [Header("场景布置")] public GameObject image; public GameObject image1; public GameObject image2; public TextMeshProUGUI text; [Header("按钮设置")] public Button startButton; public Button loseButton; public Button winButton; [Header("UI 元素路径")] public string tmpTextPath = "Canvas/DialoguePanel/TMPText"; public string startButtonPath = "Canvas/Buttons/StartButton"; public string winButtonPath = "Canvas/Buttons/WinButton"; public string loseButtonPath = "Canvas/Buttons/LoseButton"; public string imagePath = "Canvas/Background"; private bool isTyping = false; private Coroutine typingCoroutine; private string currentSentence; public DialogueState currentState = DialogueState.Before; public int currentDialogueIndex = 0; private List<string> currentDialogueList; private TextMeshProUGUI _currentTmpText; private Button _currentStartButton; private Button _currentWinButton; private Button _currentLoseButton; private GameObject _currentImage; void Awake() { // 单例模式实现 if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); SceneManager.sceneLoaded += OnSceneLoaded; Debug.Log("对话管理器初始化完成"); } else { Destroy(gameObject); return; } } void Start() { // 初始状态加载 LoadInitialState(); } void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void LoadInitialState() { // 确保对话列表初始化 InitializeDialogueLists(); Debug.Log("加载初始对话状态..."); // 检查存档中的对话状态 if (SaveSystem.Instance != null && SaveSystem.Instance.SaveExists()) { DialogueState savedState = SaveSystem.Instance.GetDialogueState(); int savedIndex = SaveSystem.Instance.GetDialogueIndex(); // 使用SetDialogueState确保正确初始化 SetDialogueState(savedState); currentDialogueIndex = savedIndex; Debug.Log($"从存档加载对话状态: {savedState} 索引: {savedIndex}"); } else { // 检查战斗结果 int result = PlayerPrefs.GetInt("LastBattleResult", -1); // 使用状态设置方法确保列表初始化 if (result == 1) SetDialogueState(DialogueState.Win); else if (result == 0) SetDialogueState(DialogueState.Lost); else SetDialogueState(DialogueState.Before); } // 清除状态 PlayerPrefs.DeleteKey("LastBattleResult"); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { // 仅初始化UI但不启动对话 StartCoroutine(InitializeUIWithoutDialogue()); } private IEnumerator InitializeUIWithoutDialogue() { yield return null; Debug.Log("初始化UI组件但不启动对话..."); // 仅执行UI初始化逻辑 // 不包含StartStateDialogue()调用 } private IEnumerator ReinitializeUIAfterFrame() { yield return null; // 等待一帧确保场景完全加载 Debug.Log("重新初始化UI组件..."); // 1. 重新获取当前场景的UI引用 _currentTmpText = GameObject.Find(tmpTextPath)?.GetComponent<TextMeshProUGUI>(); _currentStartButton = GameObject.Find(startButtonPath)?.GetComponent<Button>(); _currentWinButton = GameObject.Find(winButtonPath)?.GetComponent<Button>(); _currentLoseButton = GameObject.Find(loseButtonPath)?.GetComponent<Button>(); _currentImage = GameObject.Find(imagePath); // 2. 更新公共引用 if (_currentTmpText != null) { tmpText = _currentTmpText; EnsureFontLoaded(); // 确保字体加载 } if (_currentStartButton != null) startButton = _currentStartButton; if (_currentWinButton != null) winButton = _currentWinButton; if (_currentLoseButton != null) loseButton = _currentLoseButton; if (_currentImage != null) image = _currentImage; // 3. 重新绑定按钮事件 if (startButton != null) { startButton.onClick.RemoveAllListeners(); startButton.onClick.AddListener(OnStartClick); startButton.gameObject.SetActive(false); } if (loseButton != null) { loseButton.onClick.RemoveAllListeners(); loseButton.onClick.AddListener(OnLoseClick); loseButton.gameObject.SetActive(false); } if (winButton != null) { winButton.onClick.RemoveAllListeners(); winButton.onClick.AddListener(OnWinClick); winButton.gameObject.SetActive(false); } // 4. 确保事件系统存在 EnsureEventSystemExists(); // 5. 恢复UI状态 if (tmpText != null) { tmpText.gameObject.SetActive(false); } // 6. 继续之前的对话状态 StartStateDialogue(); } // 确保字体加载 private void EnsureFontLoaded() { if (tmpText == null) return; // 如果主字体丢失,使用备用字体 if (tmpText.font == null || tmpText.font.name == "Fallback") { if (fallbackFont != null) { tmpText.font = fallbackFont; Debug.Log("使用备用字体"); } else { Debug.LogError("主字体和备用字体均不可用!"); } } // 确保材质正确 if (tmpText.fontSharedMaterial == null) { Debug.LogWarning("字体材质丢失,使用默认材质"); tmpText.fontSharedMaterial = fallbackFont.material; } } void Update() { if (tmpText == null) { Debug.LogWarning("tmpText引用为空!"); return; } // 添加跳过功能:按E键跳过当前打字效果 if (Input.GetKeyDown(KeyCode.E) && isTyping) { SkipTyping(); } // 按E键继续下一句对话 else if (Input.GetKeyDown(KeyCode.E) && !isTyping && tmpText.gameObject.activeSelf) { NextSentence(); } } // 设置当前对话状态 public void SetDialogueState(DialogueState newState) { currentState = newState; currentDialogueIndex = 0; switch (newState) { case DialogueState.Before: currentDialogueList = beforeBattleDialogues; break; case DialogueState.Win: currentDialogueList = winDialogues; break; case DialogueState.Lost: currentDialogueList = lostDialogues; break; } Debug.Log($"状态已切换至: {newState}"); // 保存状态 SaveDialogueState(); } // 保存对话状态 private void SaveDialogueState() { if (SaveSystem.Instance != null) { SaveSystem.Instance.SaveDialogueState(currentState, currentDialogueIndex); } } private void InitializeDialogueLists() { // 确保所有对话列表都已初始化 if (beforeBattleDialogues == null) beforeBattleDialogues = new List<string>(); if (winDialogues == null) winDialogues = new List<string>(); if (lostDialogues == null) lostDialogues = new List<string>(); // 添加默认对话防止空列表 if (beforeBattleDialogues.Count == 0) beforeBattleDialogues.Add("默认对话:请添加战斗前对话内容"); if (winDialogues.Count == 0) winDialogues.Add("默认对话:请添加胜利后对话内容"); if (lostDialogues.Count == 0) lostDialogues.Add("默认对话:请添加失败后对话内容"); } // 启动当前状态的对话 public void StartStateDialogue() { if (currentDialogueList == null || currentDialogueList.Count == 0) { Debug.LogWarning($"当前对话列表为空! 状态: {currentState}"); // 自动恢复默认列表 SetDialogueState(currentState); } // 确保索引在有效范围内 currentDialogueIndex = Mathf.Clamp(currentDialogueIndex, 0, currentDialogueList.Count - 1); currentSentence = currentDialogueList[currentDialogueIndex]; Debug.Log($"开始对话: {currentSentence}"); // 暂停玩家移动 playercontrol player = FindObjectOfType<playercontrol>(); if (player != null) player.canMove = false; // 锁定玩家输入 Cursor.lockState = CursorLockMode.None; Cursor.visible = true; // 显示对话框UI tmpText.gameObject.SetActive(true); BringDialogueToFront(); // 确保在最前层 // 启动打字效果协程 if (isTyping) { StopCoroutine(typingCoroutine); } typingCoroutine = StartCoroutine(TypeSentence(currentSentence)); } // 确保对话框在最前层 private void BringDialogueToFront() { if (tmpText != null) { tmpText.transform.SetAsLastSibling(); Canvas canvas = tmpText.GetComponentInParent<Canvas>(); if (canvas != null) { canvas.sortingOrder = 100; // 设为最高层级 Debug.Log($"设置Canvas层级: {canvas.sortingOrder}"); } } } // 显示下一句对话 public void NextSentence() { currentDialogueIndex++; if (currentDialogueIndex < currentDialogueList.Count) { StartStateDialogue(); // 保存当前进度 SaveDialogueState(); } else { // 对话结束 EndDialogue(); } } IEnumerator TypeSentence(string sentence) { isTyping = true; tmpText.text = ""; // 确保文本颜色可见 tmpText.color = new Color(tmpText.color.r, tmpText.color.g, tmpText.color.b, 1f); // 逐字显示 foreach (char letter in sentence.ToCharArray()) { tmpText.text += letter; yield return new WaitForSeconds(typingSpeed); } isTyping = false; } // 跳过当前打字效果 public void SkipTyping() { if (isTyping && typingCoroutine != null) { StopCoroutine(typingCoroutine); tmpText.text = currentSentence; isTyping = false; } } public void EndDialogue() { Debug.Log("对话结束"); if (isTyping && typingCoroutine != null) { StopCoroutine(typingCoroutine); isTyping = false; } // 恢复玩家控制 playercontrol player = FindObjectOfType<playercontrol>(); if (player != null) player.canMove = true; // 隐藏对话框 if (tmpText != null) { tmpText.gameObject.SetActive(false); } // 根据状态显示对应按钮 switch (currentState) { case DialogueState.Before: if (startButton != null) { startButton.gameObject.SetActive(true); EventSystem.current.SetSelectedGameObject(startButton.gameObject); } break; case DialogueState.Win: if (winButton != null) { winButton.gameObject.SetActive(true); EventSystem.current.SetSelectedGameObject(winButton.gameObject); } break; case DialogueState.Lost: if (loseButton != null) { loseButton.gameObject.SetActive(true); EventSystem.current.SetSelectedGameObject(loseButton.gameObject); } break; } // 确保事件系统可用 EnsureEventSystemExists(); // 保存完成状态 SaveDialogueState(); } private void EnsureEventSystemExists() { EventSystem eventSystem = FindObjectOfType<EventSystem>(); if (eventSystem == null) { GameObject eventSystemObj = new GameObject("EventSystem"); eventSystem = eventSystemObj.AddComponent<EventSystem>(); eventSystemObj.AddComponent<StandaloneInputModule>(); Debug.Log("创建新事件系统"); } else if (eventSystem.GetComponent<StandaloneInputModule>() == null) { eventSystem.gameObject.AddComponent<StandaloneInputModule>(); Debug.Log("添加输入模块到事件系统"); } } public void OnMainMenuClick() { Debug.Log("主菜单按钮点击"); SceneManager.LoadScene("MainMenu"); } public void OnStartClick() { Debug.Log("开始作战"); SceneManager.LoadScene("Fight"); } public void OnLoseClick() { Debug.Log("失败按钮点击"); SceneManager.LoadScene("Fight"); } public void OnWinClick() { if (currentState != DialogueState.Win) { Debug.LogWarning("尝试在非胜利状态执行胜利逻辑"); return; } playercontrol player = FindObjectOfType<playercontrol>(); if (player != null) player.canMove = true; Debug.Log("执行胜利逻辑"); if (image != null) image.SetActive(false); if (image1 != null) image1.SetActive(false); if (image2 != null) image2.SetActive(false); if (text != null) text.gameObject.SetActive(false); if (tmpText != null) tmpText.gameObject.SetActive(false); if (winButton != null) winButton.gameObject.SetActive(false); // 清除对话存档 if (SaveSystem.Instance != null) { SaveSystem.Instance.SaveDialogueState(DialogueState.Before, 0); } } } 不要改我功能,我想让你解决button失灵问题
08-09
using System.Collections.Generic; using UnityEngine; using TMPro; using System.Collections; using UnityEngine.UI; using UnityEngine.SceneManagement; using UnityEngine.EventSystems; public class DialogueManager : MonoBehaviour { public enum DialogueState { Before, Win, Lost } public static DialogueManager Instance; [Header("UI Elements")] public TextMeshProUGUI tmpText; public float typingSpeed = 0.05f; public TMP_FontAsset fallbackFont; [Header("Dialogue Content")] public List<string> beforeBattleDialogues = new List<string>(); public List<string> winDialogues = new List<string>(); public List<string> lostDialogues = new List<string>(); [Header("场景布置")] public GameObject image; public GameObject image1; public GameObject image2; public TextMeshProUGUI text; [Header("按钮设置")] public Button startButton; public Button loseButton; public Button winButton; [Header("UI 元素标签")] public string tmpTextTag = "DialogueText"; public string startButtonTag = "StartButton"; public string winButtonTag = "WinButton"; public string loseButtonTag = "LoseButton"; public string backgroundTag = "DialogueBackground"; private bool isTyping = false; private Coroutine typingCoroutine; private string currentSentence; public DialogueState currentState = DialogueState.Before; public int currentDialogueIndex = 0; private List<string> currentDialogueList; public bool IsInitialized { get; private set; } = false; void Start() { LoadInitialState(); } void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); SceneManager.sceneLoaded += OnSceneLoaded; EnsurePermanentEventSystem(); } else { Destroy(gameObject); return; } } private void EnsurePermanentEventSystem() { if (FindObjectOfType<EventSystem>() == null) { GameObject eventSystem = new GameObject("PermanentEventSystem"); eventSystem.AddComponent<EventSystem>(); eventSystem.AddComponent<StandaloneInputModule>(); DontDestroyOnLoad(eventSystem); } } void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void LoadInitialState() { InitializeDialogueLists(); Debug.Log("加载初始对话状态..."); if (SaveSystem.Instance != null && SaveSystem.Instance.SaveExists()) { DialogueState savedState = SaveSystem.Instance.GetDialogueState(); int savedIndex = SaveSystem.Instance.GetDialogueIndex(); SetDialogueState(savedState); currentDialogueIndex = savedIndex; Debug.Log($"从存档加载对话状态: {savedState} 索引: {savedIndex}"); } else { int result = PlayerPrefs.GetInt("LastBattleResult", -1); if (result == 1) SetDialogueState(DialogueState.Win); else if (result == 0) SetDialogueState(DialogueState.Lost); else SetDialogueState(DialogueState.Before); } PlayerPrefs.DeleteKey("LastBattleResult"); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { StartCoroutine(DelayedUIFix()); } private IEnumerator DelayedUIFix() { yield return new WaitForEndOfFrame(); EnsureSingleEventSystem(); RefreshUIReferences(); // 使用标签查找UI元素 yield return StartCoroutine(RebindAfterSceneLoad()); Debug.Log("UI系统修复完成"); IsInitialized = true; } // 使用标签查找UI元素 private void RefreshUIReferences() { Debug.Log("使用标签查找UI元素..."); // 查找TMP文本 GameObject tmpObj = GameObject.FindGameObjectWithTag(tmpTextTag); if (tmpObj != null) { tmpText = tmpObj.GetComponent<TextMeshProUGUI>(); Debug.Log($"找到TMP文本: {tmpObj.name}"); } // 查找按钮 startButton = FindButtonByTag(startButtonTag); winButton = FindButtonByTag(winButtonTag); loseButton = FindButtonByTag(loseButtonTag); // 查找背景 GameObject bgObj = GameObject.FindGameObjectWithTag(backgroundTag); if (bgObj != null) image = bgObj; Debug.Log($"UI刷新结果: 文本={tmpText != null}, 开始按钮={startButton != null}, 胜利按钮={winButton != null}, 失败按钮={loseButton != null}"); } // 辅助方法:通过标签查找按钮 private Button FindButtonByTag(string tag) { GameObject btnObj = GameObject.FindGameObjectWithTag(tag); if (btnObj != null) { Debug.Log($"找到按钮: {btnObj.name} (标签: {tag})"); return btnObj.GetComponent<Button>(); } return null; } private IEnumerator RebindAfterSceneLoad() { yield return new WaitForEndOfFrame(); if (startButton != null) { startButton.onClick.RemoveAllListeners(); startButton.onClick.AddListener(OnStartClick); } if (winButton != null) { winButton.onClick.RemoveAllListeners(); winButton.onClick.AddListener(OnWinClick); } if (loseButton != null) { loseButton.onClick.RemoveAllListeners(); loseButton.onClick.AddListener(OnLoseClick); } } void Update() { if (tmpText == null) return; if (Input.GetKeyDown(KeyCode.E) && isTyping) { SkipTyping(); } else if (Input.GetKeyDown(KeyCode.E) && !isTyping && tmpText.gameObject.activeSelf) { NextSentence(); } } public void SetDialogueState(DialogueState newState) { currentState = newState; currentDialogueIndex = 0; switch (newState) { case DialogueState.Before: currentDialogueList = beforeBattleDialogues; break; case DialogueState.Win: currentDialogueList = winDialogues; break; case DialogueState.Lost: currentDialogueList = lostDialogues; break; } Debug.Log($"状态已切换至: {newState}"); SaveDialogueState(); } private void SaveDialogueState() { if (SaveSystem.Instance != null) { SaveSystem.Instance.SaveDialogueState(currentState, currentDialogueIndex); } } private void InitializeDialogueLists() { if (beforeBattleDialogues == null) beforeBattleDialogues = new List<string>(); if (winDialogues == null) winDialogues = new List<string>(); if (lostDialogues == null) lostDialogues = new List<string>(); if (beforeBattleDialogues.Count == 0) beforeBattleDialogues.Add("默认对话:请添加战斗前对话内容"); if (winDialogues.Count == 0) winDialogues.Add("默认对话:请添加胜利后对话内容"); if (lostDialogues.Count == 0) lostDialogues.Add("默认对话:请添加失败后对话内容"); } public void StartStateDialogue() { // 确保UI引用有效 if (tmpText == null || startButton == null) { RefreshUIReferences(); } if (currentDialogueList == null || currentDialogueList.Count == 0) { Debug.LogWarning($"当前对话列表为空! 状态: {currentState}"); SetDialogueState(currentState); } currentDialogueIndex = Mathf.Clamp(currentDialogueIndex, 0, currentDialogueList.Count - 1); currentSentence = currentDialogueList[currentDialogueIndex]; Debug.Log($"开始对话: {currentSentence}"); // 暂停玩家移动 playercontrol player = FindObjectOfType<playercontrol>(); if (player != null) player.canMove = false; Cursor.lockState = CursorLockMode.None; Cursor.visible = true; // 显示对话框 if (tmpText != null) tmpText.gameObject.SetActive(true); FixButtonLayer(); // 启动打字效果 if (isTyping && typingCoroutine != null) { StopCoroutine(typingCoroutine); } typingCoroutine = StartCoroutine(TypeSentence(currentSentence)); } private void FixButtonLayer() { if (startButton != null && startButton.transform != null) { Canvas parentCanvas = startButton.GetComponentInParent<Canvas>(); if (parentCanvas != null) { parentCanvas.sortingOrder = 100; startButton.transform.SetAsLastSibling(); } } if (image != null) { Image bgImage = image.GetComponent<Image>(); if (bgImage != null) bgImage.raycastTarget = false; } } public void NextSentence() { currentDialogueIndex++; if (currentDialogueIndex < currentDialogueList.Count) { StartStateDialogue(); SaveDialogueState(); } else { EndDialogue(); } } IEnumerator TypeSentence(string sentence) { isTyping = true; tmpText.text = ""; tmpText.color = new Color(tmpText.color.r, tmpText.color.g, tmpText.color.b, 1f); foreach (char letter in sentence.ToCharArray()) { tmpText.text += letter; yield return new WaitForSeconds(typingSpeed); } isTyping = false; } public void SkipTyping() { if (isTyping && typingCoroutine != null) { StopCoroutine(typingCoroutine); tmpText.text = currentSentence; isTyping = false; } } public void EndDialogue() { Debug.Log("对话结束"); if (isTyping && typingCoroutine != null) { StopCoroutine(typingCoroutine); isTyping = false; } playercontrol player = FindObjectOfType<playercontrol>(); if (player != null) player.canMove = true; if (tmpText != null) tmpText.gameObject.SetActive(false); // 确保按钮引用有效 RefreshUIReferences(); // 显示对应按钮 switch (currentState) { case DialogueState.Before: if (startButton != null) { startButton.gameObject.SetActive(true); if (EventSystem.current != null) { EventSystem.current.SetSelectedGameObject(startButton.gameObject); } } break; case DialogueState.Win: if (winButton != null) { winButton.gameObject.SetActive(true); if (EventSystem.current != null) { EventSystem.current.SetSelectedGameObject(winButton.gameObject); } } break; case DialogueState.Lost: if (loseButton != null) { loseButton.gameObject.SetActive(true); if (EventSystem.current != null) { EventSystem.current.SetSelectedGameObject(loseButton.gameObject); } } break; } EnsureSingleEventSystem(); SaveDialogueState(); } private void EnsureSingleEventSystem() { EventSystem[] systems = FindObjectsOfType<EventSystem>(); if (systems.Length > 1) { for (int i = 1; i < systems.Length; i++) { Destroy(systems[i].gameObject); } } if (EventSystem.current == null) { GameObject es = new GameObject("EventSystem"); es.AddComponent<EventSystem>(); es.AddComponent<StandaloneInputModule>(); DontDestroyOnLoad(es); } } public void OnMainMenuClick() { Debug.Log("主菜单按钮点击"); SceneManager.LoadScene("MainMenu"); } public void OnStartClick() { if (startButton != null) { startButton.image.color = Color.green; } Debug.Log("场景加载启动"); SceneManager.LoadScene("Fight"); } public void OnLoseClick() { Debug.Log("失败按钮点击"); SceneManager.LoadScene("Fight"); } public void OnWinClick() { if (currentState != DialogueState.Win) { Debug.LogWarning("尝试在非胜利状态执行胜利逻辑"); return; } playercontrol player = FindObjectOfType<playercontrol>(); if (player != null) player.canMove = true; Debug.Log("执行胜利逻辑"); if (image != null) image.SetActive(false); if (image1 != null) image1.SetActive(false); if (image2 != null) image2.SetActive(false); if (text != null) text.gameObject.SetActive(false); if (tmpText != null) tmpText.gameObject.SetActive(false); if (winButton != null) winButton.gameObject.SetActive(false); if (SaveSystem.Instance != null) { SaveSystem.Instance.SaveDialogueState(DialogueState.Before, 0); } } }我的button明明按动了但是没有反应
最新发布
08-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值