浏览代码

UI Fade in and out code and implementation

This implements the UI fader to black card using events and scriptable objects. To use, add a FadeChannelSO to the relevant script, assign the scriptable object, the call either Fade, FadeIn, or FadeOut. Has parameters for duration and target color. This is usable anywhere and at any time, but contains no safeguards besides preventing multiple fades from happening at the same time.

Note: This modifies the PersistentManagers scene and adds an Image UI element that it depends on.
/devlogs-3-input
IroncladLandship 4 年前
当前提交
ac869e64
共有 7 个文件被更改,包括 328 次插入0 次删除
  1. 121
      UOP1_Project/Assets/Scenes/PersistentManagers.unity
  2. 18
      UOP1_Project/Assets/ScriptableObjects/Events/UI/FadeChannelSO.asset
  3. 8
      UOP1_Project/Assets/ScriptableObjects/Events/UI/FadeChannelSO.asset.meta
  4. 58
      UOP1_Project/Assets/Scripts/Events/ScriptableObjects/UI/FadeChannelSO.cs
  5. 11
      UOP1_Project/Assets/Scripts/Events/ScriptableObjects/UI/FadeChannelSO.cs.meta
  6. 101
      UOP1_Project/Assets/Scripts/UI/FadeManager.cs
  7. 11
      UOP1_Project/Assets/Scripts/UI/FadeManager.cs.meta

121
UOP1_Project/Assets/Scenes/PersistentManagers.unity


m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 841012433}
m_CullTransparentMesh: 0
--- !u!1 &1122701836
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1122701838}
- component: {fileID: 1122701837}
m_Layer: 0
m_Name: FadeManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1122701837
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1122701836}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d4a9e678d7a028b459e5b9971e79931a, type: 3}
m_Name:
m_EditorClassIdentifier:
_fadeChannelSO: {fileID: 11400000, guid: b40bb60f3ca40164e9d7acc6992bae10, type: 2}
_fadeoutCanvas: {fileID: 7398076546395718055}
--- !u!4 &1122701838
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1122701836}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -1184.9143, y: -540, z: 0}
m_LocalScale: {x: 2.057143, y: 2.057143, z: 2.057143}
m_Children: []
m_Father: {fileID: 1387982343}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1242953036 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 3845877873755819562, guid: ff36e7f2f7928454dae0a4d9af31e076,

m_Children:
- {fileID: 624605539}
- {fileID: 363619425}
- {fileID: 1122701838}
- {fileID: 565765817888297794}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &138035865882902116
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7398076546395718055}
m_CullTransparentMesh: 0
--- !u!224 &565765817888297794
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7398076546395718055}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1387982343}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1001 &3845877872784178022
PrefabInstance:
m_ObjectHideFlags: 0

objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: ff36e7f2f7928454dae0a4d9af31e076, type: 3}
--- !u!114 &6952518526949780777
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7398076546395718055}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 0}
m_RaycastTarget: 1
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &7398076546395718055
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 565765817888297794}
- component: {fileID: 138035865882902116}
- component: {fileID: 6952518526949780777}
m_Layer: 5
m_Name: Fadeout Rectangle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1

18
UOP1_Project/Assets/ScriptableObjects/Events/UI/FadeChannelSO.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2f3f18ccb43e7594cb1a18cfbc24190e, type: 3}
m_Name: FadeChannelSO
m_EditorClassIdentifier:
_color: {r: 0, g: 0, b: 0, a: 0}
_inDuration: 1
_outDuration: 1
_holdDuration: 1

8
UOP1_Project/Assets/ScriptableObjects/Events/UI/FadeChannelSO.asset.meta


fileFormatVersion: 2
guid: b40bb60f3ca40164e9d7acc6992bae10
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:

58
UOP1_Project/Assets/Scripts/Events/ScriptableObjects/UI/FadeChannelSO.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
[CreateAssetMenu(menuName = "Events/UI/Fade Channel")]
public class FadeChannelSO : ScriptableObject
{
public UnityAction<bool, float, Color> OnEventRaised;
/// <summary>
/// Generic fade function. Communicates with <seealso cref="FadeManager.cs"/>.
/// </summary>
/// <param name="fadeIn">If true, the rectangle fades in. If false, the rectangle fades out.</param>
/// <param name="duration">How long it takes to the image to fade in/out.</param>
/// <param name="color">Target color for the image to reach. Disregarded when fading out.</param>
public void Fade(bool fadeIn, float duration, Color color)
{
if (OnEventRaised != null)
OnEventRaised.Invoke(fadeIn, duration, color);
}
/// <summary>
/// Generic fade function. Communicates with <seealso cref="FadeManager.cs"/>.
/// </summary>
/// <param name="fadeIn">If true, the rectangle fades in. If false, the rectangle fades out.</param>
/// <param name="duration">How long it takes to the image to fade in/out.</param>
public void Fade(bool fadeIn, float duration)
{
if (OnEventRaised != null)
OnEventRaised.Invoke(fadeIn, duration, new Color(0, 0, 0, 1));
}
/// <summary>
/// Fade helper function to simplify usage. Fades in the rectangle.
/// </summary>
/// <param name="duration">How long it takes to the image to fade in.</param>
/// <param name="color">Target color for the image to reach.</param>
public void FadeIn(float duration, Color color)
{
Fade(true, duration, color);
}
/// <summary>
/// Fade helper function to simplify usage. Fades in the rectangle.
/// </summary>
/// <param name="duration">How long it takes to the image to fade in.</param>
public void FadeIn(float duration)
{
Fade(true, duration, new Color(0, 0, 0, 1));
}
/// <summary>
/// Fade helper function to simplify usage. Fades out the rectangle.
/// </summary>
/// <param name="duration">How long it takes to the image to fade out.</param>
public void FadeOut(float duration)
{
Fade(false, duration, new Color(0, 0, 0, 1));
}
}

11
UOP1_Project/Assets/Scripts/Events/ScriptableObjects/UI/FadeChannelSO.cs.meta


fileFormatVersion: 2
guid: 2f3f18ccb43e7594cb1a18cfbc24190e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

101
UOP1_Project/Assets/Scripts/UI/FadeManager.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FadeManager : MonoBehaviour
{
[Header("Fadeout Event")]
[SerializeField] private FadeChannelSO _fadeChannelSO = default;
[Header("Fadeout Canvas")]
public GameObject _fadeoutCanvas = default;
private Image _imageComponent;
private bool IsCurrentlyFading = false;
/// <summary>
/// Enumerators that fades in the canvas's imageComponent to turn the screen to a flat color over time. Fadeins called simeutaneously will only fade in the earliest call and discard any others.
/// </summary>
/// <param name="duration">How long it takes to the image to fade in.</param>
/// <param name="color">Target color for the image to reach.</param>
/// <returns></returns>
private IEnumerator FadeInEnum(float duration, Color color)
{
float totalTime = 0f; // Total amount of time this coroutine has taken. Determines when the fadein will end and what color the imageComponent should be at every frame.
while (totalTime <= duration)
{
totalTime += Time.deltaTime;
_imageComponent.color = Color.Lerp(new Color(0, 0, 0, 0), color, totalTime/duration); // Sets the image's color to a mixture between total transparency and the target color, and interpolates based on the amount of time to completion.
yield return null;
}
_imageComponent.color = color; // Here to guarentee the image is exactly the requested color at the end of the loop.
IsCurrentlyFading = false;
yield return null;
}
/// <summary>
/// Enumerators that fades out the canvas's imageComponent to turn the screen to normal gameplay color over time. Fadeouts called simeutaneously will only fade out the earliest call and discard any others.
/// </summary>
/// <param name="duration">How long it takes to the image to fade out.</param>
/// <returns></returns>
private IEnumerator FadeOutEnum(float duration)
{
Color oldColor = _imageComponent.color; // Temporarily stores the old color of the image component, as we can't assume the image will always be black.
float totalTime = 0f; // Total amount of time this coroutine has taken. Determines when the fadeout will end and what color the imageComponent should be at every frame.
while (totalTime <= duration)
{
totalTime += Time.deltaTime;
_imageComponent.color = Color.Lerp(oldColor, new Color(0, 0, 0, 0), totalTime / duration); // Sets the image's color to a mixture between the old color and total transparency, and interpolates based on the amount of time to completion.
yield return null;
}
_imageComponent.color = new Color(0, 0, 0, 0); // Here to guarentee the image is fully transparent at the end of the loop.
IsCurrentlyFading = false;
yield return null;
}
private void Start()
{
_imageComponent = _fadeoutCanvas.GetComponent<Image>();
}
private void OnEnable()
{
if (_fadeChannelSO != null)
{
_fadeChannelSO.OnEventRaised += fadeGeneral;
}
}
private void OnDisable()
{
if (_fadeChannelSO != null)
{
_fadeChannelSO.OnEventRaised += fadeGeneral;
}
}
/// <summary>
/// Controls the fade-in and fade-out.
/// </summary>
/// <param name="fadeIn">If true, the rectangle fades in. If false, the rectangle fades out.</param>
/// <param name="duration">How long it takes to the image to fade in/out.</param>
/// <param name="color">Target color for the image to reach. Disregarded when fading out.</param>
private void fadeGeneral(bool fadeIn, float duration, Color color)
{
if (!IsCurrentlyFading) // Makes sure multiple fade-ins or outs don't happen at the same time. Note this will mean fadeouts called at the same time will be discarded.
{
IsCurrentlyFading = true;
if (fadeIn)
{
StartCoroutine(FadeInEnum(duration, color));
}
else
{
StartCoroutine(FadeOutEnum(duration)); // Fadeout doesn't need color, so the color parameter is disregarded.
// I would like to say that setting the color for the fadeout wouldn't be hard to implement, but I reckon most people wouldn't use it, so it would just be an unnecessary burden.
}
}
}
}

11
UOP1_Project/Assets/Scripts/UI/FadeManager.cs.meta


fileFormatVersion: 2
guid: d4a9e678d7a028b459e5b9971e79931a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存