原始场景
弹窗背景
新建一个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函数里面。