using System; using Dreamteck.Splines; using Ichni.RhythmGame.Beatmap; using UnityEngine; namespace Ichni.RhythmGame { public abstract class TrackRendererSubmodule : TrackSubmodule { #region [暴露属性字段] Fields public MeshGenerator meshGenerator; public MeshRenderer meshRenderer; public Material renderMaterial; public string materialThemeBundleName; public string materialName; public bool enableEmission; public float emissionIntensity; public bool zWrite; public Vector2 uvScale; public Vector2 uvOffset; #endregion #region [初始化与防御机制] Initialization & Defense public TrackRendererSubmodule(Track track, bool enableEmission, float emissionIntensity, bool zWrite, Vector2 uvScale, Vector2 uvOffset) : base(track) { this.enableEmission = enableEmission; this.emissionIntensity = emissionIntensity; this.materialThemeBundleName = String.Empty; this.materialName = String.Empty; this.zWrite = zWrite; this.uvScale = uvScale; this.uvOffset = uvOffset; if (!HaveSameSubmodule) { this.track.trackRendererSubmodule = this; } // 【盲区修复】: 在启用所需的轨道生成器前,强行将对象池残留里的其他轨道生成器打入休眠状态,以防止管网和曲线同屏出现重叠! DisableAllGenerators(); } private void DisableAllGenerators() { if (track.trackRenderer == null) return; if (track.trackRenderer.TryGetComponent(out SplineRenderer sr)) sr.enabled = false; if (track.trackRenderer.TryGetComponent(out PathGenerator pg)) pg.enabled = false; if (track.trackRenderer.TryGetComponent(out TubeGenerator tg)) tg.enabled = false; if (track.trackRenderer.TryGetComponent(out SurfaceGenerator sg)) sg.enabled = false; if (track.trackRenderer.TryGetComponent(out MeshRenderer mr)) mr.enabled = false; } #endregion #region [材质与网格控制] Material & Mesh Control public void ApplyMaterial(string materialThemeBundleName, string materialName) { this.materialThemeBundleName = materialThemeBundleName; this.materialName = materialName; Material mat = ThemeBundleManager.instance.GetObject(materialThemeBundleName, materialName); if(mat != null) { renderMaterial = mat; meshRenderer.material = renderMaterial; } meshRenderer.InitializeShader(); } public override void Refresh() { SetEnableZWrite(); SetEnableEmission(); SetEmissionIntensity(); SetUV(); } protected void SetMesh() { this.meshGenerator.enabled = true; if (track.trackTimeSubmodule is TrackTimeSubmoduleMovable trackTimeSubmoduleMovable) { meshGenerator.clipFrom = trackTimeSubmoduleMovable.tailPercent; meshGenerator.clipTo = trackTimeSubmoduleMovable.headPercent; } else { meshGenerator.clipFrom = 0; meshGenerator.clipTo = 1; } this.meshRenderer.enabled = true; // 短暂激活生成网格后,为了性能再度关闭自身的实时刷新。 this.meshGenerator.enabled = false; } protected void SetEnableEmission() => meshRenderer.material.SetInt("_Emission", enableEmission ? 1 : 0); protected void SetEnableZWrite() => meshRenderer.material.SetInt("_ZWrite", zWrite ? 1 : 0); protected void SetEmissionIntensity() => meshRenderer.material.SetColor("_EmissionColor", Color.white * Mathf.Pow(2, emissionIntensity)); protected void SetUV() { if (meshGenerator != null) { meshGenerator.uvScale = uvScale; meshGenerator.uvOffset = uvOffset; } } #endregion } }