点击屏幕,关闭弹框

本文介绍了一个在Unity中实现的UI面板自动关闭机制。该机制通过检测鼠标或触摸屏点击位置是否在面板外部来判断是否关闭面板。使用了RectTransform和Camera组件来获取屏幕坐标并转换为世界坐标,然后与面板的四个角的世界坐标进行比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AutoClosePanel : MonoBehaviour {
    public RectTransform rectTransform;
    public Camera uiCamera;
    
    //// Update is called once per frame
    void Update()
    {
#if UNITY_EDITOR
        if (Input.GetMouseButtonDown(0))
        {
            CheckClose(Input.mousePosition);
        }
#else
        if (Input.touchCount > 0) {
            for (int i = 0; i < Input.touchCount; i++)
            {
                CheckClose(Input.GetTouch(i).position);
            }
        }
#endif
    }

    void Close()
	{
        this.gameObject.SetActive(false);
	}

    void Show() {
        this.gameObject.SetActive(true);
    }

    void CheckClose(Vector3 clickPosition) {
        if (IsClickPanelOutsid(clickPosition))
        {
            Debug.Log("click out side");
            Close();
        }
        else {
            Debug.Log("click inside side");
        }
    }

    bool IsClickPanelOutsid(Vector3 clickPosition)
    {
       Vector3 clickWorldPos = uiCamera.ScreenToWorldPoint(clickPosition);
        Vector3[] cornerArray = new Vector3[4];// 左下,左上,右上,右下
        this.rectTransform.GetWorldCorners(cornerArray);
        Debug.Log("clickWorldPos:"+clickWorldPos);
        for (int i = 0; i < cornerArray.Length; i++)
        {
            Debug.Log("cornerArray:" + cornerArray[i]);
        }
            //Vector3 leftBottomPosition = uiCamera.WorldToScreenPoint(cornerArray[0]);
            //Vector3 rightTopPosition = uiCamera.WorldToScreenPoint(cornerArray[2]);
            //Debug.Log("leftBotomPoint:"+leftBottomPosition);
            //Debug.Log("rightTopPoint"+rightTopPosition);
            //Debug.Log("clickPosition:"+clickPosition);
        float minX = cornerArray[0].x;
        float minY = cornerArray[0].y;
        float maxX = cornerArray[2].x;
        float maxY = cornerArray[2].y;
        if (clickWorldPos.x > minX && clickWorldPos.y>minY && clickWorldPos.x < maxX && clickWorldPos.y < maxY)
        {
            return false;
        }
        return true;
    }




}

<think>我们正在解决全屏模式下点击事件导致的不显示问题。全屏模式下,点击事件可能被全屏元素拦截,导致无法显示。可能的原因:1.全屏元素覆盖了整个屏幕,导致点击事件被全屏元素捕获,而元素可能在全屏元素之外(或者被遮挡)从而无法显示。2.元素在全屏模式下需要被包含在全屏元素内,否则无法显示(全屏API要求全屏元素及其子元素才会显示)。解决方案:1.确保元素是全屏元素的子元素,这样在全屏时才能显示。2.调整事件处理,确保在全屏模式下点击事件能正确触发的显示,并且能够被正确显示在全屏元素内。根据之前的讨论,我们还需要注意全屏API调用的合法性,避免出现`Illegalinvocation`错误。步骤:1.将元素(例如一个div)作为全屏容器的子元素,这样在全屏时可以显示。2.在全屏容器内监听点击事件,然后触发显示。示例代码结构(Vue3):```vue<template><divref="fullscreenContainer"><!--这个元素将被全屏--><!--全屏内容--><button@click="toggleFullscreen">全屏</button><!--元素,全屏时也会显示,因为它是全屏元素的子元素--><divv-if="showDialog"class="dialog">这里是内容<button@click="showDialog=false">关闭</button></div></div></template><scriptsetup>import{ref}from'vue';constfullscreenContainer=ref(null);constshowDialog=ref(false);//全屏切换函数(之前已经修复了非法调用问题)consttoggleFullscreen=()=>{//调用全屏API,确保使用正确的this上下文constelement=fullscreenContainer.value;if(element){constmethod=element.requestFullscreen||element.mozRequestFullScreen||element.webkitRequestFullscreen||element.msRequestFullscreen;if(method){method.call(element);}}};//在全屏容器内添加点击事件,用于显示//注意:由于是全屏元素的子元素,所以点击事件可以触发//例如,我们可以在全屏容器上监听点击(这里用按钮触发,但也可以在其他元素上)constopenDialog=()=>{showDialog.value=true;};</script><style>.dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:white;padding:20px;z-index:1000;}</style>```说明:1.元素(.dialog)作为全屏容器的子元素,所以全屏时它会显示在全屏元素内部,因此可以显示。2.点击事件(例如一个按钮点击触发)发生在全屏容器内部,因此事件不会丢失。如果需要在全屏模式下由全屏元素内的某个元素触发,那么将触发的按钮也放在全屏容器内即可。另外,如果全屏模式下需要点击非按钮区域显示,可以在全屏容器上添加点击事件(注意判断点击的具体位置,避免误触发)。注意事项:1.全屏API要求:全屏元素必须是DOM元素,且不能是iframe(除非该iframe具有`allowfullscreen`属性)。2.样式调整:确保有足够高的z-index,并且位置正确。如果在全屏模式下仍然不显示,请检查:-
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天涯过客TYGK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值