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);
    }
}
相关推荐
爱吃小胖橘1 天前
Lua语法
开发语言·unity·lua
qq_205279051 天前
unity 读取PPT显示到屏幕功能
unity·游戏引擎·powerpoint
tiankongdeyige1 天前
Unity学习之C#的反射机制
学习·unity·c#
快乐觉主吖2 天前
Unity内嵌浏览器插件:3DWebView,显示不支持的音频/视频格式解决办法
unity
ellis19702 天前
toLua[四] Examples 03_CallLuaFunction分析
unity
大Mod_abfun2 天前
Unity游戏基础-4(人物移动、相机移动、UI事件处理 代码详解)
游戏·ui·unity·游戏引擎
大Mod_abfun3 天前
Unity游戏基础-3(UI层)
游戏·ui·unity·游戏引擎
ellis19703 天前
toLua[五] Examples 04_AccessingLuaVariables分析
unity
大有数据可视化3 天前
告别传统监控:基于Unity+IoT打造沉浸式数字孪生车间
物联网·unity·游戏引擎
雪下的新火3 天前
爆炸特效:Unity+Blender-02-火焰
unity·游戏引擎·blender·特效制作·笔记分享