unity开发记录:做一个panel弹窗,点击边上可以关闭、取消、返回

原始场景

在这里插入图片描述

弹窗背景

新建一个panel,添加button组件
在这里插入图片描述

弹窗内容框

在刚刚建的message中,在建两个子物体,分别为消息的background和消息主体

其中消息的背景也要添加一个button,并且关闭交互,但是要开着raycast target,目的是为了拦截鼠标点击。
而消息本身要关闭raycast target,等下再说为什么。

在这里插入图片描述
在这里插入图片描述

返回脚本

对message添加一个脚本
在这里插入图片描述

using UnityEngine;
using UnityEngine.UI;
public class GoBack : MonoBehaviour
{
    private void Start()
    {        
        this.GetComponent<Button>().onClick.AddListener(DeleteOrGoBack);
    }

    private void DeleteOrGoBack()
    {
        Debug.Log("DeleteOrGoBack");
        this.gameObject.SetActive(false);//隐藏物体,需要时再显示
        //Destroy(gameObject);       //删除物体重新加载
        //this.GetComponent<Renderer>().enabled = false;//3d物体
    }
}

效果

启动之后,点击蓝色范围外,棕色范围内,都可以关闭整个message

在这里插入图片描述
在这里插入图片描述

说明

红色就是消息框,当然也可以放任何按钮,画布,一系列需要放的东西,在里面做交互是不影响整个message的。

蓝色是消息框的背景,为了不让点消息框内的消息也GoBack了。

棕色是一个大按钮,为了是关闭整个message。

分析

我试了很多方法,都不行,最后用三个panel才实现,我觉得问题有这几个:

1.如果不用蓝色

没有蓝色的话,如果启用红色的raycast target,父物体也会感觉到被click了,直接GoBack,但是如果需要在红色里面做按钮交互之类的,显然不符合效果。

如果关闭红色的raycast target,意思是红色这个panel不接受鼠标点击的射线,但是会穿过红色,被背后的父物体接收到,一样会GoBack。

两个区别是,前者父物体通过子物体接收到click返回,后者穿过子物体父物体直接接收click返回。

2.如果红色添加button

添加了button,就必须要啊打开raycast target,这样确实可以不让棕色父物体接收到click,但是这样有个缺点就是没有办法在messageinfo中做内容,因为有个小按钮的存在。

简单地说是:能够实现逻辑,但是扩展性不强。

3.InfoBg的好处

因为有的时候按钮做在红色的角落,如果不小心点到边上了,直接就返回整个message了,体验会不是很好,所以infobg可以增大一些不能点击的区域。

拓展使用

因为需要弹出的内容不一样,所以把这个message作为一个预制体,把需要弹出的内容也作为一个预制体,加载的时候选择要不要背景,如果需要的话,自动把加载的内容放到messageInfo中。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace TobexbCommon
{
    public class ResMgr
    {
        private GameObject _panelMessage;
        private GameObject GetPanelBg()
        {
            if (_panelMessage== null) 
                _panelMessage= GetResources<GameObject>("Prefabs/Message");
            return GameObject.Instantiate(_panelMessage);
        }

        public T GetResources<T>(string resPath) where T : UnityEngine.Object
        {
            return Resources.Load<T>(resPath);
        }
                
        public GameObject GetInstance(string resPath,bool withBg=false)
        {
            GameObject obj = GameObject.Instantiate(GetResources<GameObject>(resPath));
            if (withBg)
            {
                GameObject bg = GetPanelBg();
                obj .transform.SetParent(bg.transform.Find("Info").transform, false);
                return bg;//注意是bg不是obj
            }
            return obj ;
        }

    }
}

  • GetResources:加载资源
  • GetPanelBg:加载message这个预制体
  • GetInstance:获取实例

如果只需要一个预制体,那withBg默认为false,如果需要有一个像弹窗一样,点周围边上的区域达到返回、退出、取消的效果,就可以传入参数true,就可以自动调用这个message,把预制体放到messageInfo下,注意返回的是整个message,不再是那个预制体。

如果点外侧需要达到别的效果,可以自定义在GoBack函数里面。

  • 4
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值