using UnityEngine; using System; using System.Collections.Generic; using Ichni.Editor; using Ichni.RhythmGame.Beatmap; namespace Ichni.RhythmGame.ThemeBundles.Basic { /// /// 自定义 2D 形状环境物体,支持从 AssetBundle 动态加载 Sprite, /// 并通过 ColorSubmodule 同步颜色。接入了 DirtyMark 集中刷新机制。 /// public partial class Custom2DShape : EnvironmentObject { #region [暴露属性字段] Exposed Fields public List themeBundleList = new List(); public List spriteNameList = new List(); public string spriteThemeBundleName; public string spriteName = "None"; public SpriteRenderer spriteRenderer; public override bool haveEmissionColor => true; #endregion #region [生命周期与工厂] Lifecycle & Factory public static Custom2DShape GenerateElement(string elementName, Guid id, List tags, bool isFirstGenerated, string themeBundleName, string objectName, GameElement parentElement, bool isStatic, string spriteThemeBundleName, string spriteName) { // 通过 EnvironmentObject.GenerateElement 创建 GameObject 并获取组件 Custom2DShape obj = EnvironmentObject.GenerateElement(elementName, id, tags, isFirstGenerated, themeBundleName, objectName, parentElement, isStatic).GetComponent(); obj.spriteThemeBundleName = spriteThemeBundleName; obj.spriteName = spriteName; return obj; } public override void FirstSetUpObject(bool isFirstGenerated) { spriteRenderer ??= GetComponentInChildren(); } public override void AfterInitialize() { UpdateSprite(); Refresh(); } // 响应由 PropertyAnimation 触发的延迟刷新 public override void OnDirtyRefresh(Dictionary flags) { Refresh(); } #endregion #region [效果核心逻辑] Core Effect Logic /// /// 从当前 ThemeBundle 获取 Sprite 资源 /// public void UpdateSprite() { if (spriteRenderer != null && !string.IsNullOrEmpty(spriteName) && spriteName != "None") { // 优先尝试直接获取 Sprite 资源(兼容老版或特殊包) Sprite sp = ThemeBundleManager.instance.GetObject(spriteThemeBundleName, spriteName); if (sp == null) { // 如果没有找到 Sprite,则从 Texture2D 列表中获取并动态创建 Sprite Texture2D tex = ThemeBundleManager.instance.GetObject(spriteThemeBundleName, spriteName); if (tex != null) { sp = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f)); } } if (sp != null) { spriteRenderer.sprite = sp; } else { Debug.LogWarning($"[Custom2DShape] 无法在包 '{spriteThemeBundleName}' 中找到 Sprite/Texture: {spriteName}"); } } } public override void Refresh() { // 同步 ColorSubmodule 的颜色状态 base.Refresh(); if (spriteRenderer != null) { spriteRenderer.color = colorSubmodule.currentBaseColor; if (colorSubmodule.emissionEnabled) { // 如果启用了发光,尝试设置发光颜色(需要对应的 Shader 支持) spriteRenderer.material.SetFloat("_EnableEmission", 1); spriteRenderer.material.SetColor("_EmissionColor", colorSubmodule.GetCurrentEmissionColor()); } } } #endregion } }