/** * Copyright(c) Live2D Inc. All rights reserved. * * Use of this source code is governed by the Live2D Open Software license * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. */ using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; namespace Live2D.Cubism.Rendering.Masking { /// /// Singleton buffer for Cubism mask related draw commands. /// [ExecuteInEditMode] public sealed class CubismMaskCommandBuffer : MonoBehaviour { /// /// Draw command sources. /// private static List Sources { get; set; } /// /// Command buffer. /// private static CommandBuffer Buffer { get; set; } /// /// True if are empty. /// private static bool ContainsSources { get { return Sources != null && Sources.Count > 0; } } /// /// Makes sure class is initialized for static usage. /// private static void Initialize() { // Initialize containers. if (Sources == null) { Sources = new List(); } if (Buffer == null) { Buffer = new CommandBuffer { name = "cubism_MaskCommandBuffer" }; } // Spawn update proxy. const string proxyName = "cubism_MaskCommandBuffer"; var proxy = GameObject.Find(proxyName); if (proxy == null) { proxy = new GameObject(proxyName) { hideFlags = HideFlags.HideAndDontSave }; if (!Application.isEditor || Application.isPlaying) { DontDestroyOnLoad(proxy); } proxy.AddComponent(); } } /// /// Registers a new draw command source. /// /// Source to add. internal static void AddSource(ICubismMaskCommandSource source) { // Make sure singleton is initialized. Initialize(); // Prevent same source from being added twice. if (Sources.Contains(source)) { return; } // Add source and force refresh. Sources.Add(source); } /// /// Deregisters a draw command source. /// /// Source to remove. internal static void RemoveSource(ICubismMaskCommandSource source) { // Make sure singleton is initialized. Initialize(); // Remove source and force refresh. Sources.RemoveAll(s => s == source); } /// /// Forces the command buffer to be refreshed. /// private static void RefreshCommandBuffer() { // Clear buffer. Buffer.Clear(); // Enqueue sources. for (var i = 0; i < Sources.Count; ++i) { Sources[i].AddToCommandBuffer(Buffer); } } #region Unity Event Handling /// /// Executes . /// private void LateUpdate() { if (!ContainsSources) { return; } // Refresh and execute buffer. RefreshCommandBuffer(); Graphics.ExecuteCommandBuffer(Buffer); } #endregion } }