188 lines
6.7 KiB
C#
188 lines
6.7 KiB
C#
using System.Collections.Generic;
|
||
using Framework.Manager;
|
||
using UnityEngine;
|
||
using UnityEngine.EventSystems;
|
||
|
||
namespace Zion.Scripts.ERP.查询需求计划平衡利库情况
|
||
{
|
||
public class DemandUIContextMenu : MonoBehaviour,IPointerClickHandler
|
||
{
|
||
/// <summary>
|
||
/// 鼠标右键图像弹出上下文菜单
|
||
/// </summary>
|
||
[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<RectTransform>();
|
||
if (rectTransform == null)
|
||
{
|
||
Debug.LogError("上下文菜单必须有RectTransform组件!");
|
||
return;
|
||
}
|
||
|
||
// 获取父级Canvas
|
||
canvas = GetComponentInParent<Canvas>();
|
||
if (canvas == null)
|
||
{
|
||
Debug.LogError("找不到父级Canvas!上下文菜单需要在Canvas下使用");
|
||
return;
|
||
}
|
||
|
||
canvasRectTransform = canvas.GetComponent<RectTransform>();
|
||
|
||
// 初始状态隐藏菜单
|
||
contextMenu.SetActive(false);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 实现鼠标点击接口
|
||
/// </summary>
|
||
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);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 在指定位置显示菜单
|
||
/// </summary>
|
||
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();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 调整菜单位置确保不超出屏幕
|
||
/// </summary>
|
||
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);
|
||
// }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查鼠标是否在菜单上方
|
||
/// </summary>
|
||
private bool IsPointerOverMenu()
|
||
{
|
||
PointerEventData eventData = new PointerEventData(EventSystem.current);
|
||
eventData.position = Input.mousePosition;
|
||
|
||
List<RaycastResult> results = new List<RaycastResult>();
|
||
EventSystem.current.RaycastAll(eventData, results);
|
||
|
||
foreach (RaycastResult result in results)
|
||
{
|
||
if (result.gameObject == contextMenu || result.gameObject.transform.IsChildOf(contextMenu.transform))
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
}
|
||
} |