使用Get.X管理如何关闭所有弹窗

 if (Get.isDialogOpen ?? false) {
    Get.back(closeOverlays: true); // 关闭所有弹窗
 }
 Get.back();// 关闭页面

本文只是一个知识点的累积。

using UnityEngine; using System.Collections; public class 聊天邀请管理器 : MonoBehaviour { // 单例模式 public static 聊天邀请管理器 Instance { get; private set; } [Header("引用")] public 聊天邀请弹窗 邀请弹窗; public 聊天系统 聊天系统; public bool 初始处于外出模式 = false; // 默认不进入外出模式 [Header("邀请设置")] public float 最小邀请间隔 = 10000f; public float 最大邀请间隔 = 30000f; public bool 调试模式 = true; private bool 处于外出模式 = false; private bool 正在聊天 = false; private Coroutine 邀请协程; private void Awake() { // 单例初始化 if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); // 可选:跨场景保持 } else { Destroy(gameObject); return; } } public void 设置正在聊天(bool 聊天中) { 正在聊天 = 聊天中; if (调试模式) Debug.Log($"聊天状态变更为: {聊天中}"); if (聊天中) { if (邀请协程 != null) { StopCoroutine(邀请协程); 邀请协程 = null; } } else if (处于外出模式 && 邀请协程 == null) { 邀请协程 = StartCoroutine(等待并邀请()); } } void Start() { // 验证引用 if (邀请弹窗 == null) Debug.LogError("聊天邀请管理器:请赋值邀请弹窗!"); else Debug.Log("聊天邀请管理器:已正确引用邀请弹窗"); // 自动查找聊天系统 if (聊天系统 == null) { 聊天系统 = FindObjectOfType<聊天系统>(); if (聊天系统 == null) Debug.LogError("聊天邀请管理器:未找到聊天系统组件!"); } // 初始状态设置 处于外出模式 = 初始处于外出模式; if (处于外出模式 && !正在聊天 && 邀请协程 == null) { 邀请协程 = StartCoroutine(等待并邀请()); } } // 显示邀请 public void 显示邀请(string 开场白, System.Action 接受回调) { if (邀请弹窗 == null) { Debug.LogError("邀请弹窗未赋值,无法显示邀请"); return; } 邀请弹窗.显示弹窗( () => { // 接受邀请回调 if (调试模式) Debug.Log("邀请被接受"); 接受回调?.Invoke(); }, () => { // 拒绝邀请回调 if (调试模式) Debug.Log("邀请被拒绝"); if (处于外出模式 && !正在聊天 && 邀请协程 == null) { 邀请协程 = StartCoroutine(等待并邀请()); } }, 开场白 // 传入开场白用于弹窗显示 ); } // 设置外出模式 public void 设置外出模式(bool 开启) { 处于外出模式 = 开启; if (调试模式) Debug.Log($"外出模式已{(开启 ? "开启" : "关闭")}"); if (开启 && !正在聊天 && 邀请协程 == null) { 邀请协程 = StartCoroutine(等待并邀请()); } else if (!开启 && 邀请协程 != null) { StopCoroutine(邀请协程); 邀请协程 = null; } } // 等待一段时间后显示邀请 private IEnumerator 等待并邀请() { while (true) { // 随机等待时间 float 等待时间 = Random.Range(最小邀请间隔, 最大邀请间隔); if (调试模式) Debug.Log($"将在 {等待时间:F1} 秒后显示下一次邀请"); yield return new WaitForSeconds(等待时间); // 检查是否仍需要显示邀请 if (处于外出模式 && !正在聊天) { 显示邀请("默认开场白", () => { if (聊天系统 != null) { 聊天系统.打开聊天窗口(); } }); break; // 显示后退出协程,等待聊天结束后重新开始 } else if (!处于外出模式 || 正在聊天) { break; } } 邀请协程 = null; } } using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using DG.Tweening; using System; using System.Collections; using System.Collections.Generic; public class 聊天邀请弹窗 : MonoBehaviour { [Header("UI元素")] public GameObject 邀请窗口; // 弹窗根对象 public Button 接受按钮; public Button 拒绝按钮; public CanvasGroup 弹窗画布组; public Text 标题文本; public Text 内容文本; public Text 倒计时文本; public GameObject 聊天框; [Header("配置")] public float 超时时间 = 30f; public float 动画时长 = 0.3f; public float 按钮缩放比例 = 1.05f; public string 默认标题 = "新的聊天邀请"; public string 默认内容 = "有人想与你聊天,是否接受?"; // 状态与队列管理 private bool 正在显示 = false; private Coroutine 倒计时协程; private Action 接受回调; private Action 拒绝回调; private Queue<弹窗数据> 弹窗队列 = new Queue<弹窗数据>(); // 弹窗数据结构 private struct 弹窗数据 { public string 标题; public string 内容; public Action 接受回调; public Action 拒绝回调; } void Awake() { // 确保对象激活(防止初始状态错误) if (!gameObject.activeSelf) gameObject.SetActive(true); // 初始化UI状态(只隐藏视觉效果,保持对象激活) 初始化UI状态(); // 检查并修复UI组件 检查并修复UI组件(); // 绑定按钮事件 绑定按钮事件(); } // 初始化UI状态(关键:保持对象激活) private void 初始化UI状态() { if (邀请窗口 != null && !邀请窗口.activeSelf) 邀请窗口.SetActive(true); if (弹窗画布组 != null) { 弹窗画布组.alpha = 0; 弹窗画布组.interactable = false; 弹窗画布组.blocksRaycasts = false; } 正在显示 = false; } // 检查并修复必要的UI组件 private void 检查并修复UI组件() { // 检查弹窗根对象 if (邀请窗口 == null) { Debug.LogError("聊天邀请弹窗:请赋值邀请窗口对象!"); return; } // 检查CanvasGroup if (弹窗画布组 == null) { 弹窗画布组 = 邀请窗口.GetComponent<CanvasGroup>(); if (弹窗画布组 == null) { 弹窗画布组 = 邀请窗口.AddComponent<CanvasGroup>(); Debug.LogWarning("聊天邀请弹窗:自动添加了CanvasGroup组件"); } } // 检查并修复按钮 修复按钮(接受按钮, "接受按钮"); 修复按钮(拒绝按钮, "拒绝按钮"); // 检查聊天框引用 if (聊天框 == null) Debug.LogError("聊天邀请弹窗:请赋值聊天框对象!"); } // 修复单个按钮(确保可交互) private void 修复按钮(Button 按钮, string 按钮名称) { if (按钮 == null) { Debug.LogError($"聊天邀请弹窗:{按钮名称}未赋值!"); return; } // 确保按钮所在对象激活 if (!按钮.gameObject.activeSelf) 按钮.gameObject.SetActive(true); // 确保按钮组件启用 按钮.enabled = true; 按钮.interactable = true; // 确保有图像组件(用于接收点击) if (按钮.GetComponent<Image>() == null) { Image img = 按钮.gameObject.AddComponent<Image>(); img.color = new Color(0, 0, 0, 0); // 透明背景 Debug.LogWarning($"聊天邀请弹窗:{按钮名称}缺少Image组件,已自动添加透明背景"); } // 确保有EventTrigger组件 if (按钮.GetComponent<EventTrigger>() == null) 按钮.gameObject.AddComponent<EventTrigger>(); } // 绑定按钮事件 private void 绑定按钮事件() { // 清除现有事件避免重复绑定 接受按钮?.onClick.RemoveAllListeners(); 拒绝按钮?.onClick.RemoveAllListeners(); // 绑定点击事件 if (接受按钮 != null) { 接受按钮.onClick.AddListener(On接受按钮点击); 初始化按钮交互(接受按钮); } if (拒绝按钮 != null) { 拒绝按钮.onClick.AddListener(On拒绝按钮点击); 初始化按钮交互(拒绝按钮); } } // 初始化按钮交互动画和事件 private void 初始化按钮交互(Button 按钮) { EventTrigger trigger = 按钮.GetComponent<EventTrigger>(); trigger.triggers.Clear(); // 鼠标进入事件 var enterEvent = new EventTrigger.Entry(); enterEvent.eventID = EventTriggerType.PointerEnter; enterEvent.callback.AddListener((data) => { Debug.Log($"{按钮.name}:鼠标进入"); 按钮.transform.DOScale(按钮缩放比例, 0.15f); }); trigger.triggers.Add(enterEvent); // 鼠标离开事件 var exitEvent = new EventTrigger.Entry(); exitEvent.eventID = EventTriggerType.PointerExit; exitEvent.callback.AddListener((data) => { Debug.Log($"{按钮.name}:鼠标离开"); 按钮.transform.DOScale(1f, 0.15f); }); trigger.triggers.Add(exitEvent); // 鼠标按下事件 var downEvent = new EventTrigger.Entry(); downEvent.eventID = EventTriggerType.PointerDown; downEvent.callback.AddListener((data) => { Debug.Log($"{按钮.name}:鼠标按下"); }); trigger.triggers.Add(downEvent); } // 显示弹窗(简化版) public void 显示弹窗(Action 接受回调函数, Action 拒绝回调函数) { 显示弹窗(默认标题, 默认内容, 接受回调函数, 拒绝回调函数); } // 显示弹窗(完整版) public void 显示弹窗(string 标题, string 内容, Action 接受回调函数, Action 拒绝回调函数) { // 如果当前有弹窗显示,加入队列等待 if (正在显示) { 弹窗队列.Enqueue(new 弹窗数据 { 标题 = 标题, 内容 = 内容, 接受回调 = 接受回调函数, 拒绝回调 = 拒绝回调函数 }); Debug.Log($"弹窗加入队列,当前队列长度:{弹窗队列.Count}"); return; } // 直接显示弹窗 内部显示弹窗(标题, 内容, 接受回调函数, 拒绝回调函数); } // 内部显示逻辑(核心修复:确保激活状态) private void 内部显示弹窗(string 标题, string 内容, Action 接受回调函数, Action 拒绝回调函数) { // 保存回调 接受回调 = 接受回调函数; 拒绝回调 = 拒绝回调函数; // 1. 确保整个弹窗层级处于激活状态 确保对象激活(); // 2. 设置文本内容 if (标题文本 != null) 标题文本.text = 标题; if (内容文本 != null) 内容文本.text = 内容; if (倒计时文本 != null) 倒计时文本.text = $"({超时时间}s)"; // 3. 重置画布组状态 弹窗画布组.alpha = 0; 弹窗画布组.interactable = true; 弹窗画布组.blocksRaycasts = true; // 4. 播放显示动画 弹窗画布组.DOFade(1, 动画时长).SetEase(Ease.OutQuad); 邀请窗口.transform.localScale = Vector3.zero; 邀请窗口.transform.DOScale(1, 动画时长).SetEase(Ease.OutBack); // 5. 安全启动协程(核心修复点) 启动倒计时协程(); 正在显示 = true; Debug.Log("弹窗显示成功"); } // 确保对象处于激活状态 private void 确保对象激活() { // 确保脚本所在对象激活 if (!gameObject.activeSelf) { gameObject.SetActive(true); Debug.Log("脚本所在对象已激活"); } // 确保弹窗根对象激活 if (!邀请窗口.activeSelf) { 邀请窗口.SetActive(true); Debug.Log("弹窗根对象已激活"); } // 确保整个层级处于激活状态 if (!gameObject.activeInHierarchy) { Debug.LogWarning("弹窗对象在非激活的父层级中,尝试修复..."); // 递归激活所有父对象 Transform current = transform; while (current != null && !current.gameObject.activeSelf) { current.gameObject.SetActive(true); current = current.parent; } } } // 安全启动倒计时协程 private void 启动倒计时协程() { // 先停止可能存在的旧协程 if (倒计时协程 != null) { StopCoroutine(倒计时协程); 倒计时协程 = null; } // 检查是否可以启动协程 if (isActiveAndEnabled && gameObject.activeInHierarchy) { 倒计时协程 = StartCoroutine(倒计时逻辑()); Debug.Log("倒计时协程已启动"); } else { Debug.LogError("无法启动协程:对象或脚本未激活!"); // 紧急处理:强制激活后重试 gameObject.SetActive(true); 邀请窗口.SetActive(true); 倒计时协程 = StartCoroutine(倒计时逻辑()); } } // 倒计时逻辑 private IEnumerator 倒计时逻辑() { float 剩余时间 = 超时时间; while (剩余时间 > 0 && 正在显示) { 剩余时间 -= Time.deltaTime; if (倒计时文本 != null) 倒计时文本.text = $"({Mathf.Ceil(剩余时间)}s)"; yield return null; } // 超时自动处理 if (正在显示) { Debug.Log("弹窗超时,自动关闭"); 隐藏弹窗(() => 拒绝回调?.Invoke()); } } // 隐藏弹窗 public void 隐藏弹窗(Action 完成回调 = null) { if (!正在显示) return; // 停止倒计时 if (倒计时协程 != null) { StopCoroutine(倒计时协程); 倒计时协程 = null; } // 播放淡出动画 弹窗画布组.DOFade(0, 动画时长).SetEase(Ease.InQuad) .OnComplete(() => { // 关键:只隐藏视觉效果,不禁用对象 弹窗画布组.interactable = false; 弹窗画布组.blocksRaycasts = false; 正在显示 = false; // 执行回调 完成回调?.Invoke(); // 显示下一个弹窗(如果有) if (弹窗队列.Count > 0) { 弹窗数据 下一个弹窗 = 弹窗队列.Dequeue(); 内部显示弹窗(下一个弹窗.标题, 下一个弹窗.内容, 下一个弹窗.接受回调, 下一个弹窗.拒绝回调); } Debug.Log("弹窗已隐藏"); }); } // 接受按钮点击 private void On接受按钮点击() { Debug.Log("接受按钮被点击"); 隐藏弹窗(() => { 接受回调?.Invoke(); if (聊天框 != null) { 聊天框.SetActive(true); Debug.Log("聊天框已显示"); } }); } // 拒绝按钮点击 private void On拒绝按钮点击() { Debug.Log("拒绝按钮被点击"); 隐藏弹窗(() => 拒绝回调?.Invoke()); } // 清理资源 private void OnDestroy() { DOTween.KillAll(); 弹窗队列.Clear(); } } using System.Collections; using System.Collections.Generic; using UnityEngine; public class 地块生成系统 : MonoBehaviour { public 地块数据库 数据库; private HashSet<(int X, int Y)> 已生成坐标 = new HashSet<(int X, int Y)>(); private Coroutine 生成协程 = null; private 地块Data 上一个地块 = null; public void 进入外出模式() { if (生成协程 != null) { StopCoroutine(生成协程); 生成协程 = null; } 生成协程 = StartCoroutine(生成单个地块()); } private IEnumerator 生成单个地块() { // 初始地块 if (数据库.地块列表.Count == 0) { 上一个地块 = new 地块Data { 序号 = 1, X = 0, Y = 0, 生态类型 = 获取随机生态类型() }; yield return StartCoroutine(请求AI生成内容(上一个地块)); } else { 上一个地块 = 数据库.地块列表[数据库.地块列表.Count - 1]; // 获取相邻坐标 var 新坐标 = 获取随机相邻坐标(上一个地块.X, 上一个地块.Y); if (已生成坐标.Contains((新坐标.x, 新坐标.y))) { Debug.Log("无法生成新地块,所有相邻坐标已被生成"); yield break; } var 新地块 = new 地块Data { 序号 = 上一个地块.序号 + 1, X = 新坐标.x, Y = 新坐标.y, 生态类型 = 获取随机生态类型() }; yield return StartCoroutine(请求AI生成内容(新地块)); 数据库.添加地块(新地块); 已生成坐标.Add((新地块.X, 新地块.Y)); } 生成协程 = null; } private IEnumerator 请求AI生成内容(地块Data 地块) { string 提示词 = $@"你是一个生态科考AI助手,现在要生成一个新的地块信息。 该地块序号为 {地块.序号},坐标为 ({地块.X}, {地块.Y}),生态类型为:{地块.生态类型}。 请根据以下要求生成内容: - 描述:简洁的环境描述(1~2句话) - 生物列表:至少3种生物(可以是动物、植物、菌类) 返回格式为 JSON,示例格式如下: {{ ""描述"": """", ""生物列表"": [""狼"", ""兔子"", ""蘑菇""] }}"; AIManager.Instance.发送消息给AI(提示词); while (AIManager.Instance.当前回复 == null) { yield return null; } string AI回复 = AIManager.Instance.当前回复; Debug.Log($"✅ AI返回地块信息:\n{AI回复}"); try { var 数据 = JsonUtility.FromJson<地块Data>(AI回复); 地块.描述 = 数据.描述; 地块.生物列表 = 数据.生物列表; } catch (System.Exception ex) { Debug.LogError("解析AI回复失败: " + ex.Message); } AIManager.Instance.当前回复 = null; // 请求开场白(临时使用) string 开场白提示词 = $@"你是一个生态科考AI助手,现在需要为以下地块生成一段开场白。 地块信息: - 序号:{地块.序号} - 坐标:({地块.X}, {地块.Y}) - 生态类型:{地块.生态类型} - 描述:{地块.描述} - 生物列表:{string.Join(", ", 地块.生物列表)} 请生成一段开场白,用于用户接受聊天邀请后显示在聊天框中。 "; AIManager.Instance.发送消息给AI(开场白提示词); while (AIManager.Instance.当前回复 == null) { yield return null; } string 开场白 = AIManager.Instance.当前回复; AIManager.Instance.当前回复 = null; // 创建临时数据,包含地块信息 + 开场白 var 临时数据 = new 地块临时信息 { 地块 = 地块, 开场白 = 开场白 }; 发出聊天邀请(临时数据); } private (int x, int y) 获取随机相邻坐标(int x, int y) { var 候选 = new List<(int x, int y)> { (x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1) }; // 随机打乱 for (int i = 0; i < 候选.Count; i++) { int j = Random.Range(0, 候选.Count); var temp = 候选[i]; 候选[i] = 候选[j]; 候选[j] = temp; } foreach (var coord in 候选) { if (!已生成坐标.Contains(coord)) { return coord; } } // 如果所有方向都已生成,返回原坐标(表示无法生成) return (x, y); } private void 发出聊天邀请(地块临时信息 临时数据) { 聊天邀请管理.Instance.显示邀请(临时数据.开场白, () => { 聊天系统.Instance.打开聊天窗口(临时数据.地块); }); } private string 获取随机生态类型() { string[] 类型 = { "森林", "草原", "沙漠", "湿地", "雪山", "沼泽", "热带雨林" }; return 类型[Random.Range(0, 类型.Length)]; } } 帮我修改,并完整输出代码
08-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HQL_seven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值