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);
    }
}
相关推荐
微三云生态系统架构师-彭丹8 小时前
任务卷轴积分系统架构设计:从任务状态机到合规风控的完整实现
unity·系统架构·游戏引擎
XR技术研习社10 小时前
从 PICO 文档看未来短期内的 Unity 版本选择
unity·游戏引擎·xr·vr
玖玥拾12 小时前
Unity 热更新(一)
unity·游戏引擎
软件黑马王子12 小时前
1.non-MonoBehaviour 单例模式泛型基类
unity·前端框架·c#
KhalilRuan1 天前
Unity性能优化
unity·性能优化·游戏引擎
ellis19701 天前
u3d IMGUI[二] 编辑器扩展
unity
五仁烧饼2 天前
Unity性能优化系列内存篇 - 移动端内存优化
unity·性能优化·游戏引擎
zhchyun20084 天前
# 【Unity UI 进阶】仿 Element UI 打造企业级 Unity UI 组件库(06)
ui·unity·游戏引擎
Behaviour5 天前
Unity游戏HybridCLR 热更新接入实战
游戏·unity·游戏引擎
LONGZETECH5 天前
新能源汽车动力电池实训教学痛点与虚拟仿真技术解决方案
c语言·3d·unity·架构·汽车·汽车教学软件