// Copyright (c) 2025 EFramework Innovation. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. using UnityEngine; using UnityEngine.UI; namespace EFramework.Unity.UIPlugin { /// /// UICameraMask 用于场景过渡,基于单例模式可以全局控制全屏遮罩效果,是一个屏幕过渡效果的控制组件。 /// /// /// /// 功能特性 /// - 提供全屏幕遮罩淡入淡出效果 /// - 支持自定义遮罩颜色和透明度 /// - 单例模式设计,便于全局调用 /// /// 使用手册 /// 1. 基本使用 /// /// 1. 添加组件: /// - 在 Canvas 下创建一个 Image 组件作为全屏遮罩 /// - 添加 CanvasGroup 组件 /// - 添加 UICameraMask 组件,并将 CanvasGroup 赋值给 ScreenMask 字段 /// /// 2. 代码控制 /// /// // 使用半透明黑色遮罩,1秒淡入淡出,最大不透明度为0.8 /// UICameraMask.Instance.SetTarget(Color.black, 1f, 0.8f); /// /// 2. 常见用例 /// /// 1. 自定义过渡效果: /// - 可以设置不同的颜色来创造不同的氛围 /// - 可以调整过渡时间控制淡入淡出速度 /// - 可以设置最大透明度控制遮罩的不透明程度 /// /// 2. 特殊效果: /// - 用于模拟闪光效果 /// - 用于表现角色失去意识的黑屏效果 /// /// 更多信息请参考模块文档。 /// [AddComponentMenu("UI/Camera Mask")] public class UICameraMask : MonoBehaviour { /// /// Instance 是全局单例。 /// public static UICameraMask Instance; /// /// ScreenMask 是屏幕遮罩的 Canvas 组,用于控制透明度。 /// 需要在 Inspector 中手动赋值。 /// public CanvasGroup ScreenMask; /// /// image 是遮罩图像组件。 /// 用于设置遮罩的颜色,自动从 ScreenMask 获取。 /// private Image image; /// /// currentAlpha 是当前遮罩透明度值。 /// 用于跟踪渐变过程中的透明度状态。 /// private float currentAlpha; /// /// maskAlphaDuration 是遮罩透明度变化的持续时间。 /// 控制淡入淡出效果的速度,默认为1秒。 /// private float maskAlphaDuration = 1f; /// /// maxAlpha 是最大的透明度值。 /// 控制遮罩的最大不透明度,范围为0-1。 /// private float maxAlpha; /// /// model 是工作模式的标记。 /// 0表示正在处理渐变效果,-1表示渐变已完成。 /// private float model; /// /// isPositive 表示是否为正向变化(淡出模式)。 /// true表示从不透明到透明,false表示从透明到不透明。 /// private bool isPositive; /// /// Awake 初始化单例实例和图像组件。 /// 在GameObject激活时自动调用。 /// private void Awake() { Instance = this; image = ScreenMask.transform.GetComponent(); } /// /// Update 每帧更新遮罩透明度变化。 /// 仅在model为0(处理中)时执行渐变处理。 /// private void Update() { if (model == 0) Process(); } /// /// OnDestroy 销毁时清理单例引用。 /// 防止场景切换后出现空引用。 /// private void OnDestroy() { Instance = null; } /// /// Process 处理遮罩透明度的渐变效果。 /// 根据 isPositive 标志决定是淡入还是淡出效果。 /// private void Process() { if (isPositive) { currentAlpha -= Time.deltaTime; if (ScreenMask != null) { ScreenMask.alpha = currentAlpha / maskAlphaDuration; if (currentAlpha <= 0) { ScreenMask.alpha = 0; currentAlpha = 0; model = -1; isPositive = false; } } } else { currentAlpha += Time.deltaTime; if (ScreenMask != null) { ScreenMask.alpha = currentAlpha / maskAlphaDuration; if (currentAlpha >= maxAlpha) { currentAlpha = maxAlpha; isPositive = true; } } } } /// /// SetTarget 设置遮罩效果的目标参数。 /// 启动一次完整的淡入淡出过程:先淡入(从透明到不透明),然后自动淡出(从不透明到透明)。 /// /// 遮罩的颜色,控制遮罩的颜色效果 /// 渐变持续时间,控制淡入淡出的速度,默认为1秒 /// 最大透明度值,控制遮罩的最大不透明度,默认为1(完全不透明) public void SetTarget(Color color, float time = 1f, float maxAlpha = 1) { isPositive = false; model = 0; if (time > 0) maskAlphaDuration = time; if (image) image.color = color; this.maxAlpha = maxAlpha; } } }