Unity中的Debug.Log()方法支持富文本

本文介绍如何在Unity的Debug.Log中显示带有颜色的文本。通过具体代码示例展示了如何结合HTML标签来改变输出文本的颜色,适用于调试时更直观地查看不同类型的输出信息。

代码:

Debug.Log("我的" + "<color=red>" + "颜色" + "</color>" + "<color=#ffffffff>" + "白色" + "</color>");

注意=前后不能有空格哦,调试的时候非常有用

效果:


using UnityEngine; using System.Collections.Generic; public class DialogueSystem : MonoBehaviour { public GameObject dialoguePrefab; // 预制体引用 private GameObject currentDialogueInstance; private DialogueManager currentManager; // 单例模式 public static DialogueSystem Instance { get; private set; } void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } // 游戏启动时自动开始对话 StartDialogueOnStart(); } // 游戏启动时自动开始对话 void StartDialogueOnStart() { // 直接打开默认对话 OpenDialogue("dialogues/story.txt/test", 1); } // 打开对话接口 public void OpenDialogue(string dialoguePath, int startId = 1) { if (currentDialogueInstance != null) { CloseCurrentDialogue(); } try { currentDialogueInstance = Instantiate(dialoguePrefab); currentManager = currentDialogueInstance.GetComponent<DialogueManager>(); if (currentManager == null) { Debug.LogError("预制体缺少DialogueManager组件!"); Destroy(currentDialogueInstance); return; } currentManager.OpenDialogue(dialoguePath, startId); } catch (System.Exception e) { Debug.LogError($"打开对话失败: {e.Message}"); } } // 关闭当前对话 public void CloseCurrentDialogue() { if (currentDialogueInstance != null) { currentManager.CloseDialogue(); Destroy(currentDialogueInstance); currentDialogueInstance = null; currentManager = null; } } } using UnityEngine; using UnityEngine.UI; using System.Collections; using System.Collections.Generic; public class DialogueManager : MonoBehaviour { public Image backgroundPanel; public Image avatarImage; public Text nameText; public Text messageText; public Transform optionsPanel; public Button continueButton; public GameObject optionButtonPrefab; // 对话数据 private Dictionary<int, DialogueNode> nodeDict = new Dictionary<int, DialogueNode>(); private DialogueNode currentNode; private bool isTyping = false; private string fullMessage; private string currentDialoguePath; // 事件回调 public delegate void DialogueEvent(int nodeId); public event DialogueEvent OnNodeStart; public event DialogueEvent OnDialogueEnd; void Start() { // 确保只绑定一次 continueButton.onClick.RemoveAllListeners(); continueButton.onClick.AddListener(OnContinueClicked); // 添加安全检查 if (continueButton == null) { Debug.LogError("继续按钮未绑定!"); } } // 外部调用接口:开始对话 public void OpenDialogue(string dialoguePath, int startId = 1) { currentDialoguePath = dialoguePath; LoadDialogue(dialoguePath); gameObject.SetActive(true); StartCoroutine(StartDialogueRoutine(startId)); } IEnumerator StartDialogueRoutine(int startId) { yield return new WaitForEndOfFrame(); // 确保UI已激活 StartDialogueNode(startId); } void LoadDialogue(string path) { nodeDict.Clear(); TextAsset jsonFile = Resources.Load<TextAsset>(path); if (jsonFile == null) { Debug.LogError("对话文件未找到: " + path); return; } DialogueTree tree = JsonUtility.FromJson<DialogueTree>( "{ \"nodes\": " + jsonFile.text + "}" ); foreach (var node in tree.nodes) { nodeDict.Add(node.id, node); } } void StartDialogueNode(int nodeId) { if (!nodeDict.ContainsKey(nodeId)) { EndDialogue(); return; } currentNode = nodeDict[nodeId]; OnNodeStart?.Invoke(nodeId); UpdateUI(); } void UpdateUI() { // 清空选项区域 foreach (Transform child in optionsPanel) { Destroy(child.gameObject); } // 更新角色信息 nameText.text = string.IsNullOrEmpty(currentNode.name) ? "" : currentNode.name; fullMessage = currentNode.msg; // 加载头像 if (!string.IsNullOrEmpty(currentNode.avatar)) { Sprite avatarSprite = Resources.Load<Sprite>(currentNode.avatar); if (avatarSprite != null) { avatarImage.sprite = avatarSprite; avatarImage.gameObject.SetActive(true); } else { Debug.LogWarning("头像未找到: " + currentNode.avatar); avatarImage.gameObject.SetActive(false); } } else { avatarImage.gameObject.SetActive(false); } // 启动打字机效果 StartCoroutine(TypewriterEffect()); // 处理选项 if (currentNode.opts != null && currentNode.opts.Length > 0) { continueButton.gameObject.SetActive(false); for (int i = 0; i < currentNode.opts.Length; i++) { CreateOptionButton(currentNode.opts[i]); } } // 显示继续按钮 else if (currentNode.nextid > 0) { continueButton.gameObject.SetActive(true); continueButton.GetComponentInChildren<Text>().text = "继续"; } // 结束对话 else { continueButton.gameObject.SetActive(true); continueButton.GetComponentInChildren<Text>().text = "结束"; } } IEnumerator TypewriterEffect() { isTyping = true; messageText.text = ""; foreach (char c in fullMessage.ToCharArray()) { messageText.text += c; yield return new WaitForSeconds(0.03f); // 调整显示速度 } isTyping = false; } void CreateOptionButton(DialogueOption option) { GameObject buttonObj = Instantiate(optionButtonPrefab, optionsPanel); buttonObj.GetComponentInChildren<Text>().text = option.msg; Button button = buttonObj.GetComponent<Button>(); button.onClick.RemoveAllListeners(); // 清除旧监听 button.onClick.AddListener(() => { // 添加节点存在性检查 int targetId = option.toId != 0 ? option.toId : option.nextid; if (nodeDict.ContainsKey(targetId)) { StartDialogueNode(targetId); } else { Debug.LogWarning($"目标节点不存在: {targetId}"); EndDialogue(); } }); } void OnContinueClicked() { if (currentNode == null) // 添加空值检查 { CloseDialogue(); return; } if (isTyping) { messageText.text = fullMessage; isTyping = false; return; } // 添加安全跳转检查 if (currentNode.nextid > 0 && nodeDict.ContainsKey(currentNode.nextid)) { StartDialogueNode(currentNode.nextid); } else { EndDialogue(); } } public void CloseDialogue() { // 解除所有事件绑定 continueButton.onClick.RemoveAllListeners(); // 移除选项按钮事件 foreach (Transform child in optionsPanel) { Button btn = child.GetComponent<Button>(); if (btn != null) btn.onClick.RemoveAllListeners(); } gameObject.SetActive(false); OnDialogueEnd?.Invoke(currentNode != null ? currentNode.id : -1); } void EndDialogue() { CloseDialogue(); OnDialogueEnd?.Invoke(currentNode.id); Debug.Log("对话结束"); } // 动态改变背景 public void ChangeBackground(string bgPath) { Sprite bgSprite = Resources.Load<Sprite>(bgPath); if (bgSprite != null) { backgroundPanel.sprite = bgSprite; } else { Debug.LogWarning("背景未找到: " + bgPath); } } // 动态改变角色立绘 public void ChangeAvatar(string avatarPath) { Sprite avatarSprite = Resources.Load<Sprite>(avatarPath); if (avatarSprite != null) { avatarImage.sprite = avatarSprite; } else { Debug.LogWarning("立绘未找到: " + avatarPath); } } } using UnityEngine; using UnityEngine.UI; using System.Collections; using System.Collections.Generic; public class DialogueManager : MonoBehaviour { public Image backgroundPanel; public Image avatarImage; public Text nameText; public Text messageText; public Transform optionsPanel; public Button continueButton; public GameObject optionButtonPrefab; // 对话数据 private Dictionary<int, DialogueNode> nodeDict = new Dictionary<int, DialogueNode>(); private DialogueNode currentNode; private bool isTyping = false; private string fullMessage; private string currentDialoguePath; // 事件回调 public delegate void DialogueEvent(int nodeId); public event DialogueEvent OnNodeStart; public event DialogueEvent OnDialogueEnd; void Start() { // 确保只绑定一次 continueButton.onClick.RemoveAllListeners(); continueButton.onClick.AddListener(OnContinueClicked); // 添加安全检查 if (continueButton == null) { Debug.LogError("继续按钮未绑定!"); } } // 外部调用接口:开始对话 public void OpenDialogue(string dialoguePath, int startId = 1) { currentDialoguePath = dialoguePath; LoadDialogue(dialoguePath); gameObject.SetActive(true); StartCoroutine(StartDialogueRoutine(startId)); } IEnumerator StartDialogueRoutine(int startId) { yield return new WaitForEndOfFrame(); // 确保UI已激活 StartDialogueNode(startId); } void LoadDialogue(string path) { nodeDict.Clear(); TextAsset jsonFile = Resources.Load<TextAsset>(path); if (jsonFile == null) { Debug.LogError("对话文件未找到: " + path); return; } DialogueTree tree = JsonUtility.FromJson<DialogueTree>( "{ \"nodes\": " + jsonFile.text + "}" ); foreach (var node in tree.nodes) { nodeDict.Add(node.id, node); } } void StartDialogueNode(int nodeId) { if (!nodeDict.ContainsKey(nodeId)) { EndDialogue(); return; } currentNode = nodeDict[nodeId]; OnNodeStart?.Invoke(nodeId); UpdateUI(); } void UpdateUI() { // 清空选项区域 foreach (Transform child in optionsPanel) { Destroy(child.gameObject); } // 更新角色信息 nameText.text = string.IsNullOrEmpty(currentNode.name) ? "" : currentNode.name; fullMessage = currentNode.msg; // 加载头像 if (!string.IsNullOrEmpty(currentNode.avatar)) { Sprite avatarSprite = Resources.Load<Sprite>(currentNode.avatar); if (avatarSprite != null) { avatarImage.sprite = avatarSprite; avatarImage.gameObject.SetActive(true); } else { Debug.LogWarning("头像未找到: " + currentNode.avatar); avatarImage.gameObject.SetActive(false); } } else { avatarImage.gameObject.SetActive(false); } // 启动打字机效果 StartCoroutine(TypewriterEffect()); // 处理选项 if (currentNode.opts != null && currentNode.opts.Length > 0) { continueButton.gameObject.SetActive(false); for (int i = 0; i < currentNode.opts.Length; i++) { CreateOptionButton(currentNode.opts[i]); } } // 显示继续按钮 else if (currentNode.nextid > 0) { continueButton.gameObject.SetActive(true); continueButton.GetComponentInChildren<Text>().text = "继续"; } // 结束对话 else { continueButton.gameObject.SetActive(true); continueButton.GetComponentInChildren<Text>().text = "结束"; } } IEnumerator TypewriterEffect() { isTyping = true; messageText.text = ""; foreach (char c in fullMessage.ToCharArray()) { messageText.text += c; yield return new WaitForSeconds(0.03f); // 调整显示速度 } isTyping = false; } void CreateOptionButton(DialogueOption option) { GameObject buttonObj = Instantiate(optionButtonPrefab, optionsPanel); buttonObj.GetComponentInChildren<Text>().text = option.msg; Button button = buttonObj.GetComponent<Button>(); button.onClick.RemoveAllListeners(); // 清除旧监听 button.onClick.AddListener(() => { // 添加节点存在性检查 int targetId = option.toId != 0 ? option.toId : option.nextid; if (nodeDict.ContainsKey(targetId)) { StartDialogueNode(targetId); } else { Debug.LogWarning($"目标节点不存在: {targetId}"); EndDialogue(); } }); } void OnContinueClicked() { if (currentNode == null) // 添加空值检查 { CloseDialogue(); return; } if (isTyping) { messageText.text = fullMessage; isTyping = false; return; } // 添加安全跳转检查 if (currentNode.nextid > 0 && nodeDict.ContainsKey(currentNode.nextid)) { StartDialogueNode(currentNode.nextid); } else { EndDialogue(); } } public void CloseDialogue() { // 解除所有事件绑定 continueButton.onClick.RemoveAllListeners(); // 移除选项按钮事件 foreach (Transform child in optionsPanel) { Button btn = child.GetComponent<Button>(); if (btn != null) btn.onClick.RemoveAllListeners(); } gameObject.SetActive(false); OnDialogueEnd?.Invoke(currentNode != null ? currentNode.id : -1); } void EndDialogue() { CloseDialogue(); OnDialogueEnd?.Invoke(currentNode.id); Debug.Log("对话结束"); } // 动态改变背景 public void ChangeBackground(string bgPath) { Sprite bgSprite = Resources.Load<Sprite>(bgPath); if (bgSprite != null) { backgroundPanel.sprite = bgSprite; } else { Debug.LogWarning("背景未找到: " + bgPath); } } // 动态改变角色立绘 public void ChangeAvatar(string avatarPath) { Sprite avatarSprite = Resources.Load<Sprite>(avatarPath); if (avatarSprite != null) { avatarImage.sprite = avatarSprite; } else { Debug.LogWarning("立绘未找到: " + avatarPath); } } } NullReferenceException: Object reference not set to an instance of an object DialogueManager.CreateOptionButton (DialogueOption option) (at Assets/DialogueSystem/DialogueManager.cs:165) DialogueManager.UpdateUI () (at Assets/DialogueSystem/DialogueManager.cs:131) DialogueManager.StartDialogueNode (System.Int32 nodeId) (at Assets/DialogueSystem/DialogueManager.cs:87) DialogueManager.OnContinueClicked () (at Assets/DialogueSystem/DialogueManager.cs:204) UnityEngine.Events.InvokableCall.Invoke () (at /Volumes/jenkins1/sharedspace/ra_2022.3/Runtime/Export/UnityEvent/UnityEvent.cs:178) UnityEngine.Events.UnityEvent.Invoke () (at /Volumes/jenkins1/sharedspace/ra_2022.3/artifacts/generated/UnityEvent/UnityEvent_0.cs:57) UnityEngine.UI.Button.Press () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:70) UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:114) UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:57) UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:272) UnityEngine.EventSystems.EventSystem:Update() (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)我的button界面是由三个button来组成的
08-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值