Unity3D游戏制作之 UI框架设计(四):模态窗体管理

  我们在开发UI窗体时,对于“弹出窗体”往往因为需要玩家优先处理弹出小窗体,则要求玩家不能(无法)点击“父窗体”,这种窗体就是典型的“模态窗体”。在此笔者设计了四种模式类型:完全透明、半透明、低透明度、透明且可以穿透。

对于“模态窗体”的基本实现原理是:

    在弹出窗体的后面增加一层“UI遮罩窗体”,当需要弹出特定模态窗体时,脚本自动控制“UI遮罩窗体”的“层级”,把弹出模特窗体与普通窗体之间进行隔离,起到突出显示与遮挡用户点击其他窗体的作用。

在上图左边的层级视图中,有一个“UIMaskPanel”的特殊窗体,这就是“UI遮罩窗体”,在不需要弹出显示的时候,这个窗体是“禁用”状态。 为了更好适用不同开发需求,对于弹出窗体,我们上面定义了关于弹出窗体的不同性质: 完全透明、半透明、低透明度、透明且可以穿透。 这四种类型功能的实现原理是控制“_UIMaskPanel”的颜色数值以及透明度实现的,

说明: 上图右边属性就是“UI遮罩窗体”的属性栏,笔者通过脚本控制Image组件的Color 组件,来实现"模态窗体”的不同显示性质。

   原理讲完,贴出控制代码如下:

public class UIMaskMgr : MonoBehaviour
{
    /*  字段 */
    //本脚本私有单例
    private static UIMaskMgr _Instance = null;
    //UI根节点对象
    private GameObject _GoCanvasRoot = null;
    //UI脚本节点对象
    private Transform _TraUIScriptsNode = null;
    //顶层面板
    private GameObject _GoTopPanel;
    //遮罩面板
    private GameObject _GoMaskPanel;
    //UI摄像机
    private Camera _UICamera;
    //UI摄像机原始的“层深”
    private float _OriginalUICameralDepth;

    //得到实例
    public static UIMaskMgr Instance()
    {
        if (_Instance == null)
        {
            _Instance = new GameObject("_UIMaskMgr").AddComponent<UIMaskMgr>();
        }
        return _Instance;
    }
    private UIMaskMgr() { }
    void Awake()
    {
        //得到UI根节点对象、脚本节点对象
        _GoCanvasRoot = GameObject.FindGameObjectWithTag("Canvas");
        _TraUIScriptsNode = UnityHelper.FindTheChildNode(_GoCanvasRoot, "Scripts");
        //把本脚本实例,作为“脚本节点对象”的子节点。
        UnityHelper.AddChildNodeToParentNode(_TraUIScriptsNode, gameObject.transform);
        //得到“顶层面板”、“遮罩面板”
        _GoTopPanel = _GoCanvasRoot;
        _GoMaskPanel = UnityHelper.FindTheChildNode(_GoCanvasRoot, "UiMaskPanel").gameObject;
        //得到UI摄像机原始的“层深”
        _UICamera = GameObject.FindGameObjectWithTag("TagUiCamera").GetComponent<Camera>();
        if (_UICamera != null)
        {
            //得到UI摄像机原始“层深”
            _OriginalUICameralDepth = _UICamera.depth;
        }
        else
        {
            Debug.Log(GetType() + "/Start()/UI_Camera is Null!,Please Check! ");
        }
    }

    /// <summary>
    /// 设置遮罩状态
    /// </summary>
    /// <param name="goDisplayUIForms">需要显示的UI窗体</param>
    /// <param name="lucenyType">显示透明度属性</param>
    public void SetMaskWindow(GameObject goDisplayUIForms, UiTransparencyType lucenyType = UiTransparencyType.Transparency)
    {
        //顶层窗体下移
        _GoTopPanel.transform.SetAsLastSibling();
        //启用遮罩窗体以及设置透明度
        switch (lucenyType)
        {
            //完全透明,不能穿透
            case UiTransparencyType.Transparency:
                _GoMaskPanel.SetActive(true);
                Color newColor1 = new Color(255 / 255F, 220 / 255F, 220 / 255F, 50F / 255F);
                _GoMaskPanel.GetComponent<Image>().color = newColor1;
                break;
            //半透明,不能穿透
            case UiTransparencyType.Translucence:
                _GoMaskPanel.SetActive(true);
                Color newColor2 = new Color(220 / 255F, 220 / 255F, 220 / 255F, 50F / 255F);
                _GoMaskPanel.GetComponent<Image>().color = newColor2;
                break;
            //低透明,不能穿透
            case UiTransparencyType.ImPenetrable:
                _GoMaskPanel.SetActive(true);
                Color newColor3 = new Color(50 / 255F, 50 / 255F, 50 / 255F, 200F / 255F);
                _GoMaskPanel.GetComponent<Image>().color = newColor3;
                break;
            //可以穿透
            case UiTransparencyType.Penetrable:
                if (_GoMaskPanel.activeInHierarchy)
                {
                    _GoMaskPanel.SetActive(false);
                }
                break;

            default:
                break;
        }

        //遮罩窗体下移
        _GoMaskPanel.transform.SetAsLastSibling();
        //显示窗体的下移
        goDisplayUIForms.transform.SetAsLastSibling();
        //增加当前UI摄像机的层深(保证当前摄像机为最前显示)
        if (_UICamera != null)
        {
            _UICamera.depth = _UICamera.depth + 100;    //增加层深
        }

    }

    /// <summary>
    /// 取消遮罩状态
    /// </summary>
    public void CancelMaskWindow()
    {
        //顶层窗体上移
        _GoTopPanel.transform.SetAsFirstSibling();
        //禁用遮罩窗体
        if (_GoMaskPanel.activeInHierarchy)
        {
            //隐藏
            _GoMaskPanel.SetActive(false);
        }

        //恢复当前UI摄像机的层深 
        if (_UICamera != null)
        {
            _UICamera.depth = _OriginalUICameralDepth;  //恢复层深
        }
    }
}

以上所讲解的是大体实现思路,还有很多的小细节由于时间关系没有披露,所以特提供下载链接,

项目源码工程下载地址:https://github.com/AnderTroy/UIFrameWork

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值