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);
    }
}
相关推荐
在路上看风景16 分钟前
15. 纹理尺寸是4的倍数
unity
AT~3 小时前
unity 使用Socket和protobuf实现网络连接
unity·游戏引擎
怣疯knight9 小时前
Cocos creator判断节点是否能用的方法
unity·cocos2d
tealcwu9 小时前
Google Play的Keystore不可用时的解决方法
unity
呼呼突突9 小时前
Unity使用TouchSocket的RPC
unity·rpc·游戏引擎
qq 180809511 天前
从零构建一个多目标多传感器融合跟踪器
unity
平行云1 天前
实时云渲染支持在网页上运行UE5开发的3A大作Lyra项目
unity·云原生·ue5·webgl·虚拟现实·实时云渲染·像素流送
鹏飞于天1 天前
Shader compiler initialization error: Failed to read D3DCompiler DLL file
unity
wonder135791 天前
UGUI重建流程和优化
unity·游戏开发·ugui
那个村的李富贵1 天前
Unity打包Webgl后 本地运行测试
unity·webgl