游戏UI框架设计(四)

--模态窗体管理

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

  (透明不能穿透)

(半透明不能穿透)

(低透明度,不能穿透)

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

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

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

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

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

 /***
*
* Title: "SUIFW" UI框架项目
* 主题: UI遮罩管理器
* Description:
* 功能: 负责“弹出窗体”模态显示实现
*
* Date: 2017
* Version: 0.1版本
* Modify Recoder:
*
*
*/
using System.Collections;
using System.Collections.Generic;
using System.Net.Mime;
using UnityEngine;
using UnityEngine.UI; namespace SUIFW
{
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 GetInstance()
{
if (_Instance==null)
{
_Instance = new GameObject("_UIMaskMgr").AddComponent<UIMaskMgr>();
}
return _Instance;
} void Awake()
{
//得到UI根节点对象、脚本节点对象
_GoCanvasRoot = GameObject.FindGameObjectWithTag(SysDefine.SYS_TAG_CANVAS);
_TraUIScriptsNode = UnityHelper.FindTheChildNode(_GoCanvasRoot, SysDefine.SYS_SCRIPTMANAGER_NODE);
//把本脚本实例,作为“脚本节点对象”的子节点。
UnityHelper.AddChildNodeToParentNode(_TraUIScriptsNode,this.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,UIFormLucenyType lucenyType=UIFormLucenyType.Lucency)
{
//顶层窗体下移
_GoTopPanel.transform.SetAsLastSibling();
//启用遮罩窗体以及设置透明度
switch (lucenyType)
{
//完全透明,不能穿透
case UIFormLucenyType.Lucency:
print("完全透明");
_GoMaskPanel.SetActive(true);
Color newColor1=new Color(/255F,/255F,/255F,0F/255F);
_GoMaskPanel.GetComponent<Image>().color = newColor1;
break;
//半透明,不能穿透
case UIFormLucenyType.Translucence:
print("半透明");
_GoMaskPanel.SetActive(true);
Color newColor2 = new Color(/255F, /255F, /255F, /255F);
_GoMaskPanel.GetComponent<Image>().color = newColor2;
break;
//低透明,不能穿透
case UIFormLucenyType.ImPenetrable:
print("低透明");
_GoMaskPanel.SetActive(true);
Color newColor3=new Color(/255F,/255F,/255F,200F/255F);
_GoMaskPanel.GetComponent<Image>().color = newColor3;
break;
//可以穿透
case UIFormLucenyType.Pentrate:
print("允许穿透");
if (_GoMaskPanel.activeInHierarchy)
{
_GoMaskPanel.SetActive(false);
}
break; default:
break;
} //遮罩窗体下移
_GoMaskPanel.transform.SetAsLastSibling();
//显示窗体的下移
goDisplayUIForms.transform.SetAsLastSibling();
//增加当前UI摄像机的层深(保证当前摄像机为最前显示)
if (_UICamera!=null)
{
_UICamera.depth = _UICamera.depth + ; //增加层深
} } /// <summary>
/// 取消遮罩状态
/// </summary>
public void CancelMaskWindow()
{
//顶层窗体上移
_GoTopPanel.transform.SetAsFirstSibling();
//禁用遮罩窗体
if (_GoMaskPanel.activeInHierarchy)
{
//隐藏
_GoMaskPanel.SetActive(false);
} //恢复当前UI摄像机的层深
if (_UICamera != null)
{
_UICamera.depth = _OriginalUICameralDepth; //恢复层深
}
} }
}

关于上述定义的UIMaskMgr.cs 脚本代码 ,笔者在“BaseUIForm.cs” 中做了封装,使其可以在框架中自动管理,无需框架外客户程序的处理。BaseUIForm.cs 代码如下:

 /***
*
* Title: "SUIFW" UI框架项目
* 主题: UI窗体的父类
* Description:
* 功能:定义所有UI窗体的父类。
* 定义四个生命周期
*
* 1:Display 显示状态。
* 2:Hiding 隐藏状态
* 3:ReDisplay 再显示状态。
* 4:Freeze 冻结状态。
*
*
* Date: 2017
* Version: 0.1版本
* Modify Recoder:
*
*
*/
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Design;
using UnityEngine; namespace SUIFW
{
public class BaseUIForm : MonoBehaviour {
/*字段*/
private UIType _CurrentUIType=new UIType(); /* 属性*/
//当前UI窗体类型
public UIType CurrentUIType
{
get { return _CurrentUIType; }
set { _CurrentUIType = value; }
} #region 窗体的四种(生命周期)状态 /// <summary>
/// 显示状态
/// </summary>
public virtual void Display()
{
this.gameObject.SetActive(true);
//设置模态窗体调用(必须是弹出窗体)
if (_CurrentUIType.UIForms_Type==UIFormType.PopUp)
{
UIMaskMgr.GetInstance().SetMaskWindow(this.gameObject,_CurrentUIType.UIForm_LucencyType);
}
} /// <summary>
/// 隐藏状态
/// </summary>
public virtual void Hiding()
{
this.gameObject.SetActive(false);
//取消模态窗体调用
if (_CurrentUIType.UIForms_Type == UIFormType.PopUp)
{
UIMaskMgr.GetInstance().CancelMaskWindow();
}
} /// <summary>
/// 重新显示状态
/// </summary>
public virtual void Redisplay()
{
this.gameObject.SetActive(true);
//设置模态窗体调用(必须是弹出窗体)
if (_CurrentUIType.UIForms_Type == UIFormType.PopUp)
{
UIMaskMgr.GetInstance().SetMaskWindow(this.gameObject, _CurrentUIType.UIForm_LucencyType);
}
} /// <summary>
/// 冻结状态
/// </summary>
public virtual void Freeze()
{
this.gameObject.SetActive(true);
} #endregion }
}

以上所讲解的是大体实现思路,还有很多的小细节由于时间关系没有披露,所以特提供下载链接,供感兴趣的开发者研究讨论。欢迎大家提供进一步完善的思路与建议。

本游戏UI框架(截止到以上部分)下载参考链接: 链接:http://pan.baidu.com/s/1nv4plFV 密码:6o0n

先讲解到这,我们下次讲解: 游戏UI框架设计(五):配置管理与日志系统

游戏UI框架设计(四) : 模态窗体管理的更多相关文章

  1. 游戏UI框架设计(二) : 最简版本设计

    游戏UI框架设计(二) --最简版本设计 为降低难度决定先讲解一个最简版本,阐述UI框架的核心设计理念.这里先定义三个核心功能: 1:UI窗体的自动加载功能. 2:缓存UI窗体. 3:窗体生命周期(状 ...

  2. 游戏UI框架设计(三) : 窗体的层级管理

    游戏UI框架设计(三) ---窗体的层级管理 UI框架中UI窗体的"层级管理",最核心的问题是如何进行窗体的显示管理.窗体(预设)的显示我们前面定义了三种类型: 普通.隐藏其他.反 ...

  3. 游戏UI框架设计(一) : 架构设计理论篇

    游戏UI框架设计(一) ---架构设计理论篇 前几天(2017年2月)看到一篇文章,国内王健林.马云等大咖们看好的未来十大最有"钱途"产业中,排名第一的就是"泛娱乐&qu ...

  4. 游戏UI框架设计(五): 配置管理与应用

    游戏UI框架设计(五) --配置管理与应用 在开发企业级游戏/VR/AR产品时候,我们总是希望可以总结出一些通用的技术体系,框架结构等,为简化我们的开发起到"四两拨千金"的作用.所 ...

  5. 游戏UI框架设计(7): 资源国际化技术

    游戏UI框架设计(7) --资源国际化技术 说起"资源国际化"技术,个人认为可以追述到微软Window2000 PC操作系统的发布,在这之前windows98操作系统的开发都是先由 ...

  6. 游戏UI框架设计(6): 消息传递中心

    游戏UI框架设计(6) --消息传递中心 最近一直忙于一个益智类游戏的研发工作,所以博客有段时间没有更新了.经过朋友的督促,决定这两天立刻完成最后的两篇博客讲解(UI框架).说起“消息传递中心”,或者 ...

  7. JavaScript框架设计(四) 字符串选择器(选择器模块结束)

    JavaScript框架设计(四) 字符串选择器(选择器模块结束) 经过前面JavaScript框架设计(三) push兼容性和选择器上下文的铺垫,实现了在某一元素下寻找,现在终于进入了字符串选择器 ...

  8. 《开源框架那些事儿22》:UI框架设计实战

    UI是User Interface的缩写.通常被觉得是MVC中View的部分,作用是提供跟人机交互的可视化操作界面. MVC中Model提供内容给UI进行渲染,用户通过UI框架产生响应,一般而言会由控 ...

  9. 自己动手设计并实现一个linux嵌入式UI框架(设计)

    看了"自己动手设计并实现一个linux嵌入式UI框架"显然没有尽兴,因为还没有看到庐山真面目,那我今天继续,先来说说,我用到了哪些知识背景.如:C语言基础知识,尤其是指针.函数指针 ...

随机推荐

  1. 超强JavaScript编辑器WebStorm代码提示迟缓问题及其它想到的

    去D2后发现 Hedger 的js编辑器是webStorm,便下载来试试,结果发现: 虽然WebStorm的js的提示远远不如aptana那么强悍(输入字母d不提示document),但是做为 Int ...

  2. Android文件管理,实现全选,删除等操作

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 1.例中数据是读 ...

  3. 一个好的函数(gcd)求最小公约数

    这个函数是我无意中看到的很不错,很给力,我喜欢 是用于求最小公约数的 简单的描述就是,记gcd(a,b)表示非负整数a,b的最大公因数,那么:gcd(a,b)=gcd(b,a%b)或者gcd(a,0) ...

  4. 使用 GitHub, Jekyll 打造自己的免费独立博客

    使用 GitHub, Jekyll 打造自己的免费独立博客 GitHub是一个代码托管网站,现在很多开源项目都放在GitHub上. 利用GitHub,可以让全球各地的程序员们一起协作开发.GitHub ...

  5. 变形transform的副作用

    前面的话   变形transform本来是一个用来处理移动.旋转.缩放和倾斜等基本操作的CSS3属性,但该属性除了完成其本职工作之后,还对普通元素造成了意想不到的影响,本文将详细介绍transform ...

  6. java服务器获取客户端ip

    在写服务端代码时,有时需要对客户端ip做认证,比如限制只有某些ip能访问,或者1个ip1天只能访问几次.最近就碰到个需要限制ip的情况,从网上找了一些服务器获取客户端ip的方法,说的都不太完善,这里整 ...

  7. [译]如何定义python源文件的文件编码

    简介 这篇文章是为了介绍定义python源文件文件编码的方法.python解释器可以根据所指定的编码信息对当前文件进行解析.通常来说,这种方法可以提高解析器对Unicode编码的源文件的识别,并且支持 ...

  8. 只为粗暴看一下ES6的字符串模板的性能

    网上查找"ES6 字符串模板 +性能"5分钟无果遂写了一个暴力测试. 测试对象: +=方式,字符串累加计算方式 +s1+s2...+sn方式,即传统连加拼接字符串方式 s.push ...

  9. Mcaca+Python 测试环境搭建及上手

    Macaca是一套面向用户端软件的测试解决方案,提供了自动化驱动,周边工具,集成方案,旨在解决终端上的测试.自动化.性能等方面的问题,很多人选择它的原因简单:轻量化(相比于appium),跨平台(wi ...

  10. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...