遊戲UI框架設計(四)html
--模態窗體管理框架
咱們在開發UI窗體時,對於「彈出窗體」每每由於須要玩家優先處理彈出小窗體,則要求玩家不能(沒法)點擊「父窗體」,這種窗體就是典型的「模態窗體」。在此筆者設計了四種模式類型:徹底透明、半透明、低透明度、透明且能夠穿透。ide
(透明不能穿透)this
(半透明不能穿透)spa
(低透明度,不能穿透)設計
對於「模態窗體」的基本實現原理是:3d
在彈出窗體的後面增長一層「UI遮罩窗體」,當須要彈出特定模態窗體時,腳本自動控制「UI遮罩窗體」的「層級」,把彈出模特窗體與普通窗體之間進行隔離,起到突出顯示與遮擋用戶點擊其餘窗體的做用。原理以下圖所示:日誌
在上圖左邊的層級視圖中,有一個「_UIMaskPanel」的特殊窗體,這就是「UI遮罩窗體」,在不須要彈出顯示的時候,這個窗體是「禁用」狀態。 爲了更好適用不一樣開發需求,對於彈出窗體,咱們上面定義了關於彈出窗體的不一樣性質: 徹底透明、半透明、低透明度、透明且能夠穿透。 這四種類型功能的實現原理是控制「_UIMaskPanel」的顏色數值以及透明度實現的,見下圖所示:code
說明: 上圖右邊屬性就是「UI遮罩窗體」的屬性欄,筆者經過腳本控制Image組件的Color 組件,來實現"模態窗體」的不一樣顯示性質。orm
原理講完,貼出控制代碼以下:
/***
*
* 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(255/255F,255/255F,255/255F,0F/255F);
_GoMaskPanel.GetComponent<Image>().color = newColor1;
break;
//半透明,不能穿透
case UIFormLucenyType.Translucence:
print("半透明");
_GoMaskPanel.SetActive(true);
Color newColor2 = new Color(220/255F, 220/255F, 220/255F, 50/255F);
_GoMaskPanel.GetComponent<Image>().color = newColor2;
break;
//低透明,不能穿透
case UIFormLucenyType.ImPenetrable:
print("低透明");
_GoMaskPanel.SetActive(true);
Color newColor3=new Color(50/255F,50/255F,50/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 + 100; //增長層深
}
}
/// <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
說明: 若是有想進一步查看筆者更加詳細的視頻講解,請圍觀如下地址:
連接: http://edu.51cto.com/course/course_id-8411.html
先講解到這,咱們下次講解: 遊戲UI框架設計(五):配置管理與日誌系統