NGUI实现反向定位到层级面板结点

目的:方便还原工种快速定位到结点

操作:Game视图下,鼠标悬浮UI,双击F,反向定位到层级面板的结点

cs 复制代码
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class UIHoverFinder : MonoBehaviour 
{
    float lastFKeyTime = -1f;
    float doubleClickDur = 0.3f; // 0.3秒内算双击

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.F))
        {
            if (Time.time - lastFKeyTime < doubleClickDur)
            {
                // 检测到双击F键
                OnDoubleFKey();
                lastFKeyTime = -1f; // 重置
            }
            else
            {
                lastFKeyTime = Time.time;
            }
        }
    }

    private void OnDoubleFKey()
    {
        GameObject hovered = UICamera.hoveredObject;
        if (hovered != null)
        {
            //判断没有BoxCollider时是否点击到
            Vector3 mousePos = Input.mousePosition;
            UIWidget[] allWidgets = hovered.transform.GetComponentsInChildren<UIWidget>();
            UIWidget res=null;
            for (int i = 0; i < allWidgets.Length; i++)
            {
                Rect screenRect = GetScreenRect(allWidgets[i]);
                if (screenRect.Contains(mousePos))
                {
                    if (res == null || allWidgets[i].depth > res.depth)
                    {
                        res = allWidgets[i];
                    }
                }
            }
            UnityEditor.Selection.activeGameObject = res!=null?res.gameObject:hovered;
        }
        else
        {
            Debug.Log("鼠标下没有NGUI控件");
        }
    }
    
    private Rect GetScreenRect(UIWidget widget)
    {
        if (widget == null) return new Rect();

        // 获取四个世界角点
        Vector3[] corners = widget.worldCorners;
        if (corners == null || corners.Length < 4) return new Rect();

        // 找到对应的摄像机
        Camera cam = NGUITools.FindCameraForLayer(widget.gameObject.layer);
        if (cam == null) return new Rect();

        // 转换到屏幕坐标
        Vector3 v0 = cam.WorldToScreenPoint(corners[0]);
        Vector3 v2 = cam.WorldToScreenPoint(corners[2]);

        // 注意:Unity屏幕坐标y轴是从下到上
        float xMin = Mathf.Min(v0.x, v2.x);
        float yMin = Mathf.Min(v0.y, v2.y);
        float width = Mathf.Abs(v2.x - v0.x);
        float height = Mathf.Abs(v2.y - v0.y);

        return new Rect(xMin, yMin, width, height);
    }
}
相关推荐
X_StarX2 小时前
【Unity笔记01】基于单例模式的简单UI框架
笔记·ui·unity·单例模式·游戏引擎·游戏开发·大学生
九班长2 小时前
Golang服务端处理Unity 3D游戏地图与碰撞的详细实现
3d·unity·golang
Thomas_YXQ12 小时前
Unity3D DOTS场景流式加载技术
java·开发语言·unity
KhalilRuan16 小时前
Unity-MMORPG内容笔记-其一
unity·游戏引擎
向宇it20 小时前
【unity游戏开发——网络】网络游戏通信方案——强联网游戏(Socket长连接)、 弱联网游戏(HTTP短连接)
网络·http·游戏·unity·c#·编辑器·游戏引擎
切韵10 天前
Unity编辑器扩展:UI绑定复制工具
ui·unity·编辑器
11 天前
Lua复习之何为闭包
开发语言·unity·游戏引擎·lua·交互
深空数字孪生11 天前
2025年小程序地图打车的5大技术革新:实时路况预测与智能调度升级
大数据·人工智能·unity·性能优化·小程序·游戏引擎
程序猿多布11 天前
Unity Addressable使用之检测更新流程
unity·addressable