有四种模式 完全透明 半透明 低透明 透明可以穿透
然后在
下添加一个Panle然后UGUI是按顺序往后的遮挡
这样弹出窗口就无法点击了 记得失活掉
创建Mask管理类
/**
*Copyright(C) 2019 by DefaultCompany
*All rights reserved.
*FileName: UIMaskMgr.cs
*Author: why
*Version: 1.0
*UnityVersion:2018.3.9f1
*Date: 2019-05-12
*Description: UI遮罩管理器
* 负责"弹出窗体"的实现
*History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace UIFrameWork
{
public class UIMaskMgr : MonoBehaviour
{
public static UIMaskMgr instance;
//UI根节点对象
Transform traRoot;
//UI脚本节点对象
Transform traUISprites;
//顶层面板
Transform TopPanle;
//遮罩面板
Transform MaskPanle;
//UI相机
Camera UICamera;
//UI相机初始层深
float OriginalUICameraDepth;
private void Awake()
{
instance = this;
traRoot = GameObject.FindGameObjectWithTag(SysDefine.canvasTag).transform;
traUISprites = UnityHelper.Find(traRoot, SysDefine.ScriptsMgrNode);
//把脚本节点添加到总脚本的子节点
UnityHelper.SetParent(traUISprites, gameObject.transform);
//得到顶层面版 遮罩面板
TopPanle = traRoot;
MaskPanle = UnityHelper.Find(traRoot, "UIMaskPanel");
//得到UI摄像机原始的层深
UICamera = GameObject.FindGameObjectWithTag(SysDefine.UICameraTag).GetComponent<Camera>();
if (UICamera != null)
{
OriginalUICameraDepth = UICamera.depth;
}
else
{
Debug.Log($"{GetType()} UICamera==null Please Check!");
}
}
/// <summary>
/// 设置遮罩状态
/// </summary>
/// <param name="ActiveUI">需要显示的UI窗体</param>
/// <param name="type"></param>
public void SetMaskWnd(Transform activeUI, UIFormLucenyType type = UIFormLucenyType.Lucency)
{
//顶层窗体下移 防止多个canvas遮挡
TopPanle.SetAsLastSibling();
//启用遮罩窗体以及设置透明度
Color newCol=Color.white;
switch (type)
{
case UIFormLucenyType.Lucency:
MaskPanle.gameObject.SetActive(true);
newCol = new Color(1, 1, 1, 0);
break;
case UIFormLucenyType.Translucence:
MaskPanle.gameObject.SetActive(true);
newCol = new Color(1, 1, 1, 0.2f);
break;
case UIFormLucenyType.ImPenetrable:
MaskPanle.gameObject.SetActive(true);
newCol = new Color(1, 1, 1, 0.8f);
break;
case UIFormLucenyType.Pentrate:
if (MaskPanle.gameObject.activeInHierarchy)
{
MaskPanle.gameObject.SetActive(false);
}
break;
}
MaskPanle.GetComponent<Image>().color = newCol;
//遮罩窗体下移
TopPanle.SetAsLastSibling();
//显示窗体的下移
activeUI.SetAsLastSibling();
//增加当前UI摄像机层深(保证当前摄像机为最前显示)
if (UICamera != null)
{
OriginalUICameraDepth = UICamera.depth + 100;
}
}
/// <summary>
/// 取消遮罩状态
/// </summary>
public void CancleMaskWnd()
{
//顶层窗体上移
TopPanle.transform.SetAsFirstSibling();
//禁用遮罩窗体 如果激活则禁用
if (MaskPanle.gameObject.activeInHierarchy)
{
MaskPanle.gameObject.SetActive(false);
}
if (UICamera != null)
{
//恢复层深
UICamera.depth = OriginalUICameraDepth;
}
}
}
}
在BaseUI里添加方法
/**
*Copyright(C) 2019 by DefaultCompany
*All rights reserved.
*FileName: BaseUI.cs
*Author: why
*Version: 1.0
*UnityVersion:2017.2.2f1
*Date: 2019-05-10
*Description: UI窗体父类
*定义UI窗体的父类
* 有四个生命周期
* 1.Display显示状态
* 2.Hiding隐藏状态
* 3.ReDisplay再显示状态
* 4.Freeze冻结状态 就是弹出窗体后面的窗体冻结
*History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UIFrameWork
{
//窗体类型
public class UIType
{
/// <summary>
/// 是否清空"栈集合" 反向切换
/// </summary>
public bool isClearStack = false;
/// <summary>
/// UI窗体(位置)类型
/// </summary>
public UIFormType type = UIFormType.Normal;
/// <summary>
///UI窗体显示类型
/// </summary>
public UIFormShowMode mode = UIFormShowMode.Normal;
/// <summary>
/// UI窗体透明度类型
/// </summary>
public UIFormLucenyType lucenyType = UIFormLucenyType.Lucency;
}
public class BaseUI : MonoBehaviour
{
public UIType currentUIType { get; set; } = new UIType();
#region 窗体的四种状态(生命周期)
/// <summary>
/// 显示状态
/// </summary>
public virtual void ActiveTrue()
{
gameObject.SetActive(true);
//设置弹出窗体调用
if (currentUIType.type==UIFormType.PopUp)
{
UIMaskMgr.instance.SetMaskWnd(gameObject.transform, currentUIType.lucenyType);
}
}
/// <summary>
/// 隐藏状态
/// </summary>
public virtual void ActiveFalse()
{
gameObject.SetActive(false);
if (currentUIType.type == UIFormType.PopUp)
{
UIMaskMgr.instance.CancleMaskWnd();
}
}
/// <summary>
/// 重新显示状态
/// </summary>
public virtual void ReActiveTrue()
{
gameObject.SetActive(true);
if (currentUIType.type == UIFormType.PopUp)
{
UIMaskMgr.instance.SetMaskWnd(gameObject.transform, currentUIType.lucenyType);
}
}
/// <summary>
/// 冻结状态
/// </summary>
public virtual void Freeze()
{
gameObject.SetActive(true);
}
#endregion
#region 封装子类常用方法
/// <summary>
/// 注册按钮事件
/// </summary>
protected void RigisterBtnOnClick(string btnName, EventTriggerListener.VoidDelegate del)
{
Transform btn = UnityHelper.Find(gameObject.transform, btnName);
EventTriggerListener.Get(btn?.gameObject).onClick = del;
}
protected void RigisterBtnOnClick(Transform btn, EventTriggerListener.VoidDelegate del)
{
EventTriggerListener.Get(btn?.gameObject).onClick = del;
}
/// <summary>
/// 打开UI窗体
/// </summary>
/// <param name="UIName"></param>
protected void OpenUI(string UIName)
{
UIManager.instance.ShowUI(UIName);
}
/// <summary>
/// 关闭UI窗体
/// </summary>
protected void CloseUI()
{
string UIName;
//int intPos = -1;
//命名空间+类名
UIName = GetType().ToString();
//查询第一次出现在这在第几位
//intPos = UIName.IndexOf('.');
//if (intPos != -1)
//{
// UIName = UIName.Substring(intPos + 1);
//}
UIManager.instance.CloseUI(UIName);
}
#endregion
}
}
创建一个空节点 绑定脚本
把之前的Main Shop 界面添加脚本
/**
*Copyright(C) 2019 by DefaultCompany
*All rights reserved.
*FileName: ShopUI.cs
*Author: why
*Version: 1.0
*UnityVersion:2018.3.9f1
*Date: 2019-05-12
*Description: 商店UI
*History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UIFrameWork;
public class ShopUI : BaseUI
{
private void Awake()
{
currentUIType.type = UIFormType.PopUp;
currentUIType.lucenyType = UIFormLucenyType.ImPenetrable;
currentUIType.mode = UIFormShowMode.ReverseChange;
RigisterBtnOnClick("btnClose", go => { CloseUI(); });
}
}
/**
*Copyright(C) 2019 by DefaultCompany
*All rights reserved.
*FileName: MainUI.cs
*Author: why
*Version: 1.0
*UnityVersion:2018.3.9f1
*Date: 2019-05-12
*Description: 主场景显示
*History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UIFrameWork;
public class MainUI : BaseUI
{
void Awake()
{
currentUIType.mode = UIFormShowMode.HideOther;
RigisterBtnOnClick("btnShop", go=>OpenUI(ProConst.ShopUI));
}
}
然后就是这样后面不能点
shop lucenyType改为可穿透 后面的就可以点 不过一般最好不要用 容易混乱 把能点的最好写到一个层级
然后就这样了 后面的也可以点
记得在UIManager注册 之后会改为读表
其他的没改什么了
配置管理
这样可以不写死 可以一键改语言版本
主要现在有两种方式XML Json (Excle也行用C#7的元组 但是自身没有节点概念)
XML:对于数据的精确表示、易读性高
微软都很多项目都内置对XML作为配置文件的支持
缺点 读写速度慢,这个问题移动端尤其突出
Json:轻量级数据交换格式 读写速度快 易读性没XML好 不过可以接受。
本框架就都用Json配置吧
Json解析方法
-
.NET自带的序列化反序列化json工具
System.Runtime.Serialization.Json
缺点 要写大量代码 封装一些实用方法 不推荐
2.litejson插件
3.Unity5.3版本以上 自带Json解析API推荐
官方机翻
记得用txt写json写的时候 另存为修改编码 ANSI不支持中文
开发Json配置管理器 类似于之前XML表读写
导入到Resources目录下
根据之前起的名字改一下
里面蓝色的参数必须要跟
这三个名字对应