using System.Collections.Generic; using Framework.Manager; using UnityEngine; using UnityEngine.EventSystems; namespace Zion.Scripts.ERP.查询需求计划平衡利库情况 { public class DemandUIContextMenu : MonoBehaviour,IPointerClickHandler { /// /// 鼠标右键图像弹出上下文菜单 /// [Tooltip("鼠标右键点击后显示的菜单")] public GameObject contextMenu; [Tooltip("是否在显示菜单时跟随鼠标位置")] public bool followMouse = true; private RectTransform rectTransform; private Canvas canvas; private RectTransform canvasRectTransform; private void Awake() { // 确保有菜单引用 if (contextMenu == null) { Debug.LogError("上下文菜单未设置!请指定一个GameObject作为菜单"); return; } // 获取菜单的RectTransform组件 rectTransform = contextMenu.GetComponent(); if (rectTransform == null) { Debug.LogError("上下文菜单必须有RectTransform组件!"); return; } // 获取父级Canvas canvas = GetComponentInParent(); if (canvas == null) { Debug.LogError("找不到父级Canvas!上下文菜单需要在Canvas下使用"); return; } canvasRectTransform = canvas.GetComponent(); // 初始状态隐藏菜单 contextMenu.SetActive(false); } /// /// 实现鼠标点击接口 /// public void OnPointerClick(PointerEventData eventData) { // 检查是否为右键点击 if (eventData.button == PointerEventData.InputButton.Right) { // 显示/隐藏菜单 if (contextMenu.activeSelf) { contextMenu.SetActive(false); } else { // 显示菜单并设置位置 ShowMenuAtPosition(eventData.position); TutorialGuideManager.Instance.TriggerNextGuide(this.name); } } else if (eventData.button == PointerEventData.InputButton.Left && contextMenu.activeSelf) { // 左键点击时如果菜单已经打开,则关闭菜单 contextMenu.SetActive(false); } } /// /// 在指定位置显示菜单 /// private void ShowMenuAtPosition(Vector2 position) { contextMenu.SetActive(true); Debug.Log("屏幕坐标: " + position); if (canvas.renderMode == RenderMode.ScreenSpaceOverlay) { // ScreenSpaceOverlay模式下直接使用屏幕坐标 rectTransform.position = position; } else { // 将屏幕坐标转换为Canvas中的局部坐标 RectTransformUtility.ScreenPointToLocalPointInRectangle( canvasRectTransform, position, canvas.worldCamera, out Vector2 localPoint ); Debug.Log("转换后的Canvas局部坐标: " + localPoint); rectTransform.anchoredPosition = localPoint; } // 确保菜单不超出屏幕边界 AdjustMenuPosition(); } /// /// 调整菜单位置确保不超出屏幕 /// private void AdjustMenuPosition() { // 获取菜单的尺寸 Vector2 menuSize = rectTransform.sizeDelta; // 获取当前位置 Vector2 position = rectTransform.anchoredPosition; // 获取Canvas的尺寸 Vector2 canvasSize = canvasRectTransform.sizeDelta; // 检查右边界 float rightEdge = position.x + menuSize.x / 2; if (rightEdge > canvasSize.x / 2) { position.x = canvasSize.x / 2 - menuSize.x / 2; } // 检查左边界 float leftEdge = position.x - menuSize.x / 2; if (leftEdge < -canvasSize.x / 2) { position.x = -canvasSize.x / 2 + menuSize.x / 2; } // 检查上边界 float topEdge = position.y + menuSize.y / 2; if (topEdge > canvasSize.y / 2) { position.y = canvasSize.y / 2 - menuSize.y / 2; } // 检查下边界 float bottomEdge = position.y - menuSize.y / 2; if (bottomEdge < -canvasSize.y / 2) { position.y = -canvasSize.y / 2 + menuSize.y / 2; } // 更新位置 rectTransform.anchoredPosition = new Vector2(position.x+70, position.y-70); } private void Update() { // // 如果点击了其他地方,关闭菜单 // if (contextMenu.activeSelf && Input.GetMouseButtonDown(0) && !IsPointerOverMenu()) // { // contextMenu.SetActive(false); // } } /// /// 检查鼠标是否在菜单上方 /// private bool IsPointerOverMenu() { PointerEventData eventData = new PointerEventData(EventSystem.current); eventData.position = Input.mousePosition; List results = new List(); EventSystem.current.RaycastAll(eventData, results); foreach (RaycastResult result in results) { if (result.gameObject == contextMenu || result.gameObject.transform.IsChildOf(contextMenu.transform)) { return true; } } return false; } } }