通过点击一个超链接打开一个新窗口,在新窗口处理完相关动作后再关闭本窗口,并刷新父窗口及聚焦到父窗口,怎么实现?...

本文介绍了一种通过点击超链接在新窗口中打开页面并执行特定操作的方法,之后能自动关闭该窗口并刷新聚焦到父窗口。同时探讨了仅刷新父窗口部分内容的技术方案。
案例:通过点击一个超链接打开一个新窗口,在新窗口处理完相关动作后再关闭本窗口,并刷新父窗口及聚焦到父窗口,怎么实现?

解决方案:
父窗口代码如下:
<a href="#" onclick="openAction()">
<bean:message key="label.new_address" /></a>

<script type="text/javascript">
function openAction(){
window.open('${ctx}/orgAddress.do?method=list&custId=${cust}','shippingWindow','scrollbars=yes,width=800,height=600,alwaysRaised=1');
}
</script>

子窗口代码如下:
<a href="#" class="button height"
onclick="return doClose()"
id="Return"
name="Return">
<span><bean:message key="button.close" /></span> </a>

<Script language="JavaScript">
<!--
function doClose(){
window.opener.location.reload();
window.opener.focus();
window.close();
}
</script>
完成上述动作就可以实现此案例所提出的问题。。。如果只是在子窗口做一个动作,然后自动定位到父窗口,那么只需要在子窗口中加入如下代码即可:
<body onUnload="window.opener.location.reload();window.opener.focus();window.close();">

深入思考:(留给自己和进入此blog朋友的作业题)
假如我只要刷新父窗口的部分内容,而不是父窗口的整个页面,那又该如何呢?
using UnityEngine.UI; using System.Collections; using DG.Tweening; using System.Collections.Generic; using UnityEngine.EventSystems; using UnityEngine; public class 聊天系统 : MonoBehaviour { // UI组件引用 public GameObject 聊天窗口; public InputField 消息输入框; public Button 发送按钮; public Button 关闭按钮; public Transform 消息容器; // 消息项的父物体(必须是ScrollView的Content) public GameObject 玩家消息预制体; // 玩家消息预制体(靠右) public GameObject 朋友消息预制体; // 朋友消息预制体(靠左) public ScrollRect 聊天滚动视图; // 手动指定滚动视图 public RectTransform 标题栏; // 用于拖拽的标题栏 // 地块信息显示 public GameObject 地块信息预制体; // 用于显示地块信息的预制体 // 聊天设置 public string 玩家名称 = "我"; public string 朋友名称 = "AI助手"; public Color 玩家消息颜色 = Color.blue; public Color 朋友消息颜色 = Color.green; public int 消息分割长度 = 20; // 消息分割长度 // 显示相关设置 public RectTransform 聊天内容区域; public bool 显示关键错误 = true; // 只保留关键错误显示控制 public Color 调试文本颜色 = Color.red; // 聊天状态 private bool 聊天窗口是否打开 = false; public 聊天邀请管理器 邀请管理器; // 字体相关 public Font 聊天字体; public int 字体大小 = 16; // UI层级相关 public Canvas 聊天画布; public int 消息文本层级 = 5; // 动画设置 public float 动画持续时间 = 0.3f; public float 缩放比例 = 0.8f; public float 弹性系数 = 1.1f; // 消息历史记录 private List<消息数据> 消息历史 = new List<消息数据>(); public int 最大消息数量 = 50; // 限制最大消息数量 // 拖拽相关变量 private bool 正在拖拽 = false; private Vector2 拖拽偏移量; private RectTransform 聊天窗口Rect; // 引用AI管理器 public AIManager ai管理器; // 当前显示的地块信息 private GameObject 当前地块信息显示 = null; public void 收到AI消息(string 内容) { // 使用朋友的名称和颜色显示AI消息 收到消息(朋友名称, 内容); } void Start() { 聊天窗口.SetActive(false); 聊天窗口是否打开 = false; 邀请管理器 = FindObjectOfType<聊天邀请管理器>(); // 获取聊天窗口的RectTransform用于拖拽 聊天窗口Rect = 聊天窗口.GetComponent<RectTransform>(); // 自动查找AI管理器 if (ai管理器 == null) { ai管理器 = FindObjectOfType<AIManager>(); if (ai管理器 != null) { ai管理器.聊天系统 = this; // 双向关联 } else if (显示关键错误) { Debug.LogWarning("场景中未找到AIManager组件,AI功能将不可用"); } } // 确保标题栏存在,若未指定则尝试查找 if (标题栏 == null) { Transform 标题栏Transform = 聊天窗口.transform.Find("标题栏"); if (标题栏Transform != null) { 标题栏 = 标题栏Transform.GetComponent<RectTransform>(); } else { 标题栏 = 聊天窗口Rect; } } // 自动查找滚动视图 if (聊天滚动视图 == null) 聊天滚动视图 = 消息容器.GetComponentInParent<ScrollRect>(); // 验证修复显示问题 验证消息显示相关组件(); 修复输入框(); 修复消息容器布局(); 修复UI层级问题(); // 绑定事件 发送按钮.onClick.RemoveAllListeners(); 发送按钮.onClick.AddListener(发送消息); 关闭按钮.onClick.RemoveAllListeners(); 关闭按钮.onClick.AddListener(关闭聊天窗口); 消息输入框.onEndEdit.RemoveAllListeners(); 消息输入框.onEndEdit.AddListener(输入框车发送); // 添加输入框按键监听,支持Ctrl+Enter换行 消息输入框.onValueChanged.AddListener(OnInputValueChanged); // 添加拖拽事件监听 添加拖拽事件监听(); StartCoroutine(监控输入框状态()); } // 添加拖拽事件监听 private void 添加拖拽事件监听() { if (标题栏 == null) return; // 添加事件触发器用于拖拽 EventTrigger trigger = 标题栏.GetComponent<EventTrigger>(); if (trigger == null) { trigger = 标题栏.gameObject.AddComponent<EventTrigger>(); } // 清除现有事件,避免重复添加 trigger.triggers.Clear(); // 鼠标按下事件 EventTrigger.Entry 按下事件 = new EventTrigger.Entry(); 按下事件.eventID = EventTriggerType.PointerDown; 按下事件.callback.AddListener((data) => 开始拖拽((PointerEventData)data)); trigger.triggers.Add(按下事件); // 鼠标拖动事件 EventTrigger.Entry 拖动事件 = new EventTrigger.Entry(); 拖动事件.eventID = EventTriggerType.Drag; 拖动事件.callback.AddListener((data) => 执行拖拽((PointerEventData)data)); trigger.triggers.Add(拖动事件); // 鼠标释放事件 EventTrigger.Entry 释放事件 = new EventTrigger.Entry(); 释放事件.eventID = EventTriggerType.PointerUp; 释放事件.callback.AddListener((data) => 结束拖拽()); trigger.triggers.Add(释放事件); // 鼠标离开事件 EventTrigger.Entry 离开事件 = new EventTrigger.Entry(); 离开事件.eventID = EventTriggerType.PointerExit; 离开事件.callback.AddListener((data) => 结束拖拽()); trigger.triggers.Add(离开事件); } // 开始拖拽 private void 开始拖拽(PointerEventData 事件数据) { 正在拖拽 = true; // 计算鼠标位置与窗口位置的偏移量 RectTransformUtility.ScreenPointToLocalPointInRectangle( 聊天窗口Rect, 事件数据.position, 事件数据.pressEventCamera, out 拖拽偏移量); } // 执行拖拽 private void 执行拖拽(PointerEventData 事件数据) { if (!正在拖拽 || 聊天窗口Rect == null) return; Vector2 本地鼠标位置; if (RectTransformUtility.ScreenPointToLocalPointInRectangle( 聊天窗口Rect.parent.GetComponent<RectTransform>(), 事件数据.position, 事件数据.pressEventCamera, out 本地鼠标位置)) { // 根据偏移量调整窗口位置 聊天窗口Rect.localPosition = 本地鼠标位置 - 拖拽偏移量; } } // 结束拖拽 private void 结束拖拽() { 正在拖拽 = false; } // 处理输入框内容变化,支持Ctrl+Enter换行 private void OnInputValueChanged(string input) { if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) { if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter)) { 消息输入框.text += "\n"; 消息输入框.caretPosition = 消息输入框.text.Length; } } } // 修复UI层级问题 private void 修复UI层级问题() { // 确保有Canvas组件 if (聊天画布 == null) { 聊天画布 = GetComponentInParent<Canvas>(); if (聊天画布 == null) { 聊天画布 = 聊天窗口.AddComponent<Canvas>(); 聊天窗口.AddComponent<CanvasScaler>(); 聊天窗口.AddComponent<GraphicRaycaster>(); } } // 确保消息容器在正确层级 if (消息容器 != null) { CanvasRenderer cr = 消息容器.GetComponent<CanvasRenderer>(); if (cr == null) { cr = 消息容器.gameObject.AddComponent<CanvasRenderer>(); } // 设置消息容器的层级 RectTransform rt = 消息容器.GetComponent<RectTransform>(); if (rt != null) { rt.SetAsLastSibling(); // 确保在最上层 } } } // 验证消息显示相关组件 private void 验证消息显示相关组件() { // 验证消息容器 if (消息容器 == null) { if (显示关键错误) Debug.LogError("错误:消息容器未赋值!"); return; } // 验证滚动视图 if (聊天滚动视图 == null) { // 移除布局提示 } else { // 确保消息容器是ScrollView的Content if (聊天滚动视图.content != 消息容器.GetComponent<RectTransform>()) { 聊天滚动视图.content = 消息容器.GetComponent<RectTransform>(); } // 修复滚动视图掩码问题 Mask mask = 聊天滚动视图.GetComponent<Mask>(); if (mask != null && !mask.showMaskGraphic) { mask.showMaskGraphic = true; } // 修复滚动条设置 if (聊天滚动视图.verticalScrollbar != null) { 聊天滚动视图.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport; 聊天滚动视图.verticalScrollbarSpacing = 2; } } // 验证预制体 if (玩家消息预制体 == null) { if (显示关键错误) Debug.LogError("错误:玩家消息预制体未赋值!"); } if (朋友消息预制体 == null) { if (显示关键错误) Debug.LogError("错误:朋友消息预制体未赋值!"); } // 检查预制体是否激活 if (玩家消息预制体 != null && !玩家消息预制体.activeSelf) { 玩家消息预制体.SetActive(true); } if (朋友消息预制体 != null && !朋友消息预制体.activeSelf) { 朋友消息预制体.SetActive(true); } // 验证文本组件 if (玩家消息预制体 != null) { Text 发送者文本 = 玩家消息预制体.transform.Find("发送者文本")?.GetComponent<Text>(); Text 内容文本 = 玩家消息预制体.transform.Find("内容文本")?.GetComponent<Text>(); if (发送者文本 == null || 内容文本 == null) { 修复消息项预制体(玩家消息预制体); } } if (朋友消息预制体 != null) { Text 发送者文本 = 朋友消息预制体.transform.Find("发送者文本")?.GetComponent<Text>(); Text 内容文本 = 朋友消息预制体.transform.Find("内容文本")?.GetComponent<Text>(); if (发送者文本 == null || 内容文本 == null) { 修复消息项预制体(朋友消息预制体); } } } // 修复消息项预制体 private void 修复消息项预制体(GameObject 预制体) { if (预制体 == null) return; // 添加发送者文本 if (预制体.transform.Find("发送者文本") == null) { GameObject 发送者文本对象 = new GameObject("发送者文本"); 发送者文本对象.transform.SetParent(预制体.transform); Text 发送者文本 = 发送者文本对象.AddComponent<Text>(); 发送者文本.font = 聊天字体 ?? Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); 发送者文本.fontSize = 字体大小; 发送者文本.color = Color.black; 发送者文本.enabled = true; 发送者文本.raycastTarget = false; // 设置位置 RectTransform rt = 发送者文本对象.GetComponent<RectTransform>(); rt.anchorMin = new Vector2(0, 1); rt.anchorMax = new Vector2(0, 1); rt.pivot = new Vector2(0, 1); rt.offsetMin = new Vector2(5, -25); rt.offsetMax = new Vector2(100, 0); } // 添加内容文本 if (预制体.transform.Find("内容文本") == null) { GameObject 内容文本对象 = new GameObject("内容文本"); 内容文本对象.transform.SetParent(预制体.transform); Text 内容文本 = 内容文本对象.AddComponent<Text>(); 内容文本.font = 聊天字体 ?? Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); 内容文本.fontSize = 字体大小; 内容文本.color = Color.black; 内容文本.enabled = true; 内容文本.raycastTarget = false; // 设置位置 RectTransform rt = 内容文本对象.GetComponent<RectTransform>(); rt.anchorMin = new Vector2(0, 1); rt.anchorMax = new Vector2(1, 1); rt.pivot = new Vector2(0, 1); rt.offsetMin = new Vector2(110, -25); rt.offsetMax = new Vector2(-5, 0); } // 移除任何可能存在的时间戳组件 Transform 时间戳Transform = 预制体.transform.Find("时间戳"); if (时间戳Transform != null) { DestroyImmediate(时间戳Transform.gameObject); } } // 修复消息容器布局 private void 修复消息容器布局() { if (消息容器 == null) return; // 确保容器激活 消息容器.gameObject.SetActive(true); // 添加垂直布局组 VerticalLayoutGroup layout = 消息容器.GetComponent<VerticalLayoutGroup>(); if (layout == null) { layout = 消息容器.gameObject.AddComponent<VerticalLayoutGroup>(); } // 修复间距和布局冲突问题 layout.spacing = 20; layout.childAlignment = TextAnchor.UpperLeft; layout.childControlWidth = true; layout.childControlHeight = true; layout.childForceExpandWidth = false; layout.childForceExpandHeight = false; layout.padding = new RectOffset(10, 10, 10, 10); // 添加内容大小适配 ContentSizeFitter fitter = 消息容器.GetComponent<ContentSizeFitter>(); if (fitter == null) { fitter = 消息容器.gameObject.AddComponent<ContentSizeFitter>(); } fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; fitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained; // 滚动视图设置优化 if (聊天滚动视图 != null) { 聊天滚动视图.vertical = true; 聊天滚动视图.horizontal = false; 聊天滚动视图.movementType = ScrollRect.MovementType.Clamped; 聊天滚动视图.content.sizeDelta = new Vector2(0, 0); 聊天滚动视图.scrollSensitivity = 40f; // 确保滚动条正确关联 if (聊天滚动视图.verticalScrollbar != null) { 聊天滚动视图.verticalScrollbar.value = 0; // 初始位置在底部 } } // 修复两个预制体的RectTransform 修复预制体RectTransform(玩家消息预制体, true); 修复预制体RectTransform(朋友消息预制体, false); } // 修复预制体的RectTransform private void 修复预制体RectTransform(GameObject 预制体, bool 是玩家消息) { if (预制体 == null) return; RectTransform rt = 预制体.GetComponent<RectTransform>(); if (rt != null) { rt.anchorMin = new Vector2(0, 1); rt.anchorMax = new Vector2(1, 1); rt.pivot = new Vector2(0.5f, 1); rt.offsetMin = new Vector2(0, 0); rt.offsetMax = new Vector2(0, 0); rt.localScale = Vector3.one; } // 确保文本可见 Text[] texts = 预制体.GetComponentsInChildren<Text>(); foreach (var text in texts) { text.enabled = true; text.font = 聊天字体 ?? Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); text.fontSize = 字体大小; text.horizontalOverflow = HorizontalWrapMode.Wrap; text.verticalOverflow = VerticalWrapMode.Overflow; } // 移除预制体中可能存在的时间戳 Transform 时间戳Transform = 预制体.transform.Find("时间戳"); if (时间戳Transform != null) { DestroyImmediate(时间戳Transform.gameObject); } } // 分割消息的方法 private List<string> 分割消息(string 内容) { List<string> 分割后的消息 = new List<string>(); // 如果消息长度小于等于分割长度,直接返原消息 if (string.IsNullOrEmpty(内容) || 内容.Length <= 消息分割长度) { 分割后的消息.Add(内容); return 分割后的消息; } // 否则按指定长度分割消息 for (int i = 0; i < 内容.Length; i += 消息分割长度) { int 截取长度 = Mathf.Min(消息分割长度, 内容.Length - i); string 子消息 = 内容.Substring(i, 截取长度); 分割后的消息.Add(子消息); } return 分割后的消息; } // 显示消息项 private void 显示消息项(string 发送者, string 内容, Color 颜色, bool 是玩家消息, bool 显示发送者 = true) { if (消息容器 == null) { if (显示关键错误) Debug.LogError("消息容器未赋值!"); return; } // 根据是否是玩家消息选择不同的预制体 GameObject 消息预制体 = 是玩家消息 ? 玩家消息预制体 : 朋友消息预制体; if (消息预制体 == null) { if (显示关键错误) Debug.LogError("消息项预制体未赋值!"); return; } // 实例化消息项 GameObject 消息项 = Instantiate(消息预制体, 消息容器); 消息项.name = $"{(是玩家消息 ? "玩家" : "朋友")}_消息_{System.DateTime.Now.Ticks}"; 消息项.SetActive(true); 消息项.transform.SetAsLastSibling(); // 初始状态设置为缩放为0,为动画做准备 消息项.transform.localScale = Vector3.zero; // 设置发送者文本 Text 发送者文本 = 消息项.transform.Find("发送者文本")?.GetComponent<Text>(); if (发送者文本 != null) { 发送者文本.text = 发送者 + ":"; 发送者文本.color = 颜色; 发送者文本.font = 聊天字体 ?? Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); 发送者文本.fontSize = 字体大小; 发送者文本.enabled = 显示发送者; 发送者文本.rectTransform.sizeDelta = new Vector2(100, 发送者文本.preferredHeight); } else if (显示关键错误) { Debug.LogError("未找到'发送者文本'组件!"); } // 设置内容文本 Text 内容文本 = 消息项.transform.Find("内容文本")?.GetComponent<Text>(); if (内容文本 != null) { 内容文本.text = 内容; 内容文本.font = 聊天字体 ?? Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); 内容文本.fontSize = 字体大小; 内容文本.enabled = true; // 计算最大宽度 float 最大宽度 = 聊天滚动视图 != null ? 聊天滚动视图.GetComponent<RectTransform>().rect.width - 120 : 300; 内容文本.rectTransform.sizeDelta = new Vector2(最大宽度, 内容文本.preferredHeight); // 强制更新文本尺寸 Canvas.ForceUpdateCanvases(); LayoutRebuilder.ForceRebuildLayoutImmediate(消息项.GetComponent<RectTransform>()); } else if (显示关键错误) { Debug.LogError("未找到'内容文本'组件!"); } // 强制刷新布局 LayoutRebuilder.ForceRebuildLayoutImmediate(消息容器.GetComponent<RectTransform>()); if (聊天内容区域 != null) LayoutRebuilder.ForceRebuildLayoutImmediate(聊天内容区域); // 应用Q弹动画效果 应用消息动画(消息项.transform); // 保存消息到历史记录 消息历史.Add(new 消息数据(发送者, 内容, System.DateTime.Now, 是玩家消息)); // 检查移除超出最大数量的消息 清理旧消息(); // 滚动到最新消息 StartCoroutine(滚动到最新消息()); } // 应用消息弹出的Q弹动画 private void 应用消息动画(Transform 消息变换) { // 确保DOTween可用 if (消息变换 == null) return; // 重置缩放 消息变换.localScale = Vector3.one * 缩放比例; // 使用DOTween创建Q弹效果 消息变换.DOScale(Vector3.one * 弹性系数, 动画持续时间 / 2) .SetEase(Ease.OutQuad) .OnComplete(() => { // 弹效果 消息变换.DOScale(Vector3.one, 动画持续时间 / 2) .SetEase(Ease.OutElastic); }); } // 滚动到最新消息 - 优化滚动效果 private IEnumerator 滚动到最新消息() { // 等待布局刷新 yield return new WaitForEndOfFrame(); if (聊天滚动视图 != null) { // 强制更新内容大小 ContentSizeFitter fitter = 消息容器.GetComponent<ContentSizeFitter>(); if (fitter != null) { fitter.SetLayoutVertical(); } // 使用动画平滑滚动到底部 float targetPos = 0; // 0表示滚动到底部 float startPos = 聊天滚动视图.verticalNormalizedPosition; float elapsedTime = 0; float duration = 0.2f; while (elapsedTime < duration) { elapsedTime += Time.deltaTime; 聊天滚动视图.verticalNormalizedPosition = Mathf.Lerp(startPos, targetPos, elapsedTime / duration); yield return null; } // 确保最终位置正确 聊天滚动视图.verticalNormalizedPosition = targetPos; } } // 清理超出最大数量的旧消息 private void 清理旧消息() { if (消息历史.Count <= 最大消息数量) return; int 要删除的数量 = 消息历史.Count - 最大消息数量; // 从容器中移除最早的消息对象 for (int i = 0; i < 要删除的数量 && 消息容器.childCount > 0; i++) { Destroy(消息容器.GetChild(0).gameObject); } // 从历史记录中移除 消息历史.RemoveRange(0, 要删除的数量); } // 验证必要组件 private void 验证必要组件() { if (消息输入框 == null && 显示关键错误) Debug.LogError("错误:消息输入框未赋值!"); if (发送按钮 == null && 显示关键错误) Debug.LogError("错误:发送按钮未赋值!"); if (关闭按钮 == null && 显示关键错误) Debug.LogError("错误:关闭按钮未赋值!"); if (聊天字体 == null) { 聊天字体 = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); if (聊天字体 == null && 消息输入框 != null && 消息输入框.textComponent != null) 聊天字体 = 消息输入框.textComponent.font; } } private void 修复输入框() { if (消息输入框 == null) return; 消息输入框.gameObject.SetActive(true); 消息输入框.enabled = true; 消息输入框.interactable = true; if (消息输入框.textComponent == null) { Text textComp = 消息输入框.GetComponentInChildren<Text>(); if (textComp == null) textComp = 消息输入框.gameObject.AddComponent<Text>(); 消息输入框.textComponent = textComp; } if (消息输入框.textComponent != null) { if (聊天字体 != null) 消息输入框.textComponent.font = 聊天字体; 消息输入框.textComponent.fontSize = 字体大小; 消息输入框.textComponent.color = Color.black; } if (消息输入框.placeholder != null) { Text placeholder = 消息输入框.placeholder.GetComponent<Text>(); if (placeholder != null) { if (聊天字体 != null) placeholder.font = 聊天字体; placeholder.text = "输入消息...(Ctrl+Enter换行)"; } } } private IEnumerator 监控输入框状态() { while (true) { if (聊天窗口是否打开 && 消息输入框 != null && !消息输入框.interactable) 消息输入框.interactable = true; yield return new WaitForSeconds(0.5f); } } public void 打开聊天窗口() { if (聊天窗口是否打开) return; 聊天窗口.SetActive(true); 聊天窗口是否打开 = true; if (消息输入框 != null) 消息输入框.text = ""; StartCoroutine(延迟聚焦输入框(0.1f)); if (邀请管理器 != null) 邀请管理器.设置正在聊天(true); } // 新增:带地块信息的打开聊天窗口方法 public void 打开聊天窗口(地块Data 地块信息) { 打开聊天窗口(); // 先调用无参数版本打开窗口 // 清除旧的地块信息 if (当前地块信息显示 != null) { Destroy(当前地块信息显示); } if (地块信息预制体 != null && 地块信息 != null) { 当前地块信息显示 = Instantiate(地块信息预制体, 消息容器); 当前地块信息显示.name = $"地块信息_{地块信息.序号}"; Text 地块描述文本 = 当前地块信息显示.transform.Find("内容文本")?.GetComponent<Text>(); if (地块描述文本 != null) { 地块描述文本.text = $@"地块信息: - 序号:{地块信息.序号} - 坐标:({地块信息.X}, {地块信息.Y}) - 生态类型:{地块信息.生态类型} - 描述:{地块信息.描述} - 生物列表:{string.Join(", ", 地块信息.生物列表)}"; } // 强制布局刷新 LayoutRebuilder.ForceRebuildLayoutImmediate(消息容器.GetComponent<RectTransform>()); StartCoroutine(滚动到最新消息()); } // 发送AI请求 if (ai管理器 != null && 地块信息 != null) { string 提示词 = $@"你是一个生态科考AI助手,现在要生成一个新的地块信息。 该地块序号为 {地块信息.序号},坐标为 ({地块信息.X}, {地块信息.Y}),生态类型为:{地块信息.生态类型}。 请根据以下要求生成内容: - 描述:简洁的环境描述(1~2句话) - 生物列表:至少3种生物(可以是动物、植物、菌类)"; ai管理器.发送消息给AI(提示词); } } private IEnumerator 延迟聚焦输入框(float 延迟时间) { yield return new WaitForSeconds(延迟时间); if (消息输入框 != null) { 消息输入框.Select(); 消息输入框.ActivateInputField(); } } public void 关闭聊天窗口() { if (!聊天窗口是否打开) return; 聊天窗口.SetActive(false); 聊天窗口是否打开 = false; if (邀请管理器 != null) 邀请管理器.设置正在聊天(false); } public void 发送消息() { if (!聊天窗口是否打开 || 消息输入框 == null) return; string 消息内容 = 消息输入框.text.Trim(); if (string.IsNullOrEmpty(消息内容)) return; // 分割消息 List<string> 分割后的消息 = 分割消息(消息内容); // 发送分割后的消息 for (int i = 0; i < 分割后的消息.Count; i++) { // 只有第一条消息显示发送者,后续分割的消息隐藏发送者 bool 显示发送者 = (i == 0); 显示消息项(玩家名称, 分割后的消息[i], 玩家消息颜色, true, 显示发送者); } // 发送消息给AI if (ai管理器 != null) { ai管理器.发送消息给AI(消息内容); } else if (显示关键错误) { Debug.LogWarning("AI管理器未找到,无法发送消息给AI"); } 消息输入框.text = ""; 消息输入框.ActivateInputField(); } private void 输入框车发送(string 内容) { if (消息输入框 == null) return; // 只有在没有按下Ctrl键时,车才发送消息 if ((Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter)) && !(Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl))) { if (聊天窗口是否打开) 发送消息(); 消息输入框.DeactivateInputField(); 消息输入框.ActivateInputField(); } } // 收到消息方法 public void 收到消息(string 发送者, string 内容) { // 分割收到的消息 List<string> 分割后的消息 = 分割消息(内容); // 显示分割后的消息 for (int i = 0; i < 分割后的消息.Count; i++) { // 只有第一条消息显示发送者,后续分割的消息隐藏发送者 bool 显示发送者 = (i == 0); 显示消息项(发送者, 分割后的消息[i], 朋友消息颜色, false, 显示发送者); } } // 在场景视图中可视化消息容器区域 void OnDrawGizmosSelected() { // 移除场景视图中的调试可视化 } // 消息数据类,用于存储消息历史 private class 消息数据 { public string 发送者; public string 内容; public System.DateTime 时间; public bool 是玩家消息; public 消息数据(string 发送者, string 内容, System.DateTime 时间, bool 是玩家消息) { this.发送者 = 发送者; this.内容 = 内容; this.时间 = 时间; this.是玩家消息 = 是玩家消息; } } private static 聊天系统 _instance; public static 聊天系统 Instance { get { if (_instance == null) { _instance = FindObjectOfType<聊天系统>(); if (_instance == null) { GameObject go = new GameObject("聊天系统"); _instance = go.AddComponent<聊天系统>(); DontDestroyOnLoad(go); } } return _instance; } } }
最新发布
08-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值