using System; using System.Collections; using System.Collections.Generic; using Dreamteck.Splines; using Ichni.RhythmGame.Beatmap; using UnityEngine; using UnityEngine.Serialization; namespace Ichni.RhythmGame { public partial class ParticleTracker : GameElement, IHaveParticles, IHaveColorSubmodule { #region [暴露属性字段] Essential Configs public Track track; public string themeBundleName; public string materialName; public bool prewarm; public float playTime; public float stopTime; public bool is3D; public float width; public Vector3 extendDirection; public float density; public float lifeTime; public bool isAutoOrient; public Vector3 particleRotation; #endregion #region [计算与状态缓存] Calculated & Cached States public ParticleController particleController; public bool haveBaseColor => true; public bool haveEmissionColor => true; #endregion #region [子模块接口] Submodules public ParticleSystem particle { get; set; } public ColorSubmodule colorSubmodule { get; set; } #endregion #region [生命周期] Lifecycle & Factory public static ParticleTracker GenerateElement(string elementName, Guid id, List tags, bool isFirstGenerated, Track track, string themeBundleName, string materialName, bool prewarm, float playTime, float stopTime, bool is3D, float width, Vector3 extendDirection, float density, float lifeTime, bool isAutoOrient, Vector3 particleRotation) { ParticleTracker particleTracker = Instantiate(GameManager.Instance.basePrefabs.particleTracker, track.transform) .GetComponent(); particleTracker.particle = particleTracker.GetComponent(); particleTracker.Initialize(elementName, id, tags, isFirstGenerated, track); particleTracker.track = track; particleTracker.particleController.spline = track.trackPathSubmodule.path; particleTracker.playTime = playTime; particleTracker.stopTime = stopTime; particleTracker.themeBundleName = themeBundleName; particleTracker.materialName = materialName; (particleTracker as IHaveParticles).SetParticleMaterial(themeBundleName, materialName); particleTracker.SetParticleSettings(prewarm, is3D, width, extendDirection, density, lifeTime, isAutoOrient, particleRotation); return particleTracker; } public override void SetDefaultSubmodules() { colorSubmodule = new ColorSubmodule(this, Color.white, true, Color.white, 0); } #endregion #region [运行时设置] Runtime Settings public void SetParticleSettings(bool prewarm, bool is3D, float width, Vector3 extendDirection, float density, float lifeTime, bool isAutoOrient, Vector3 particleRotation) { this.prewarm = prewarm; this.is3D = is3D; this.width = width; this.extendDirection = extendDirection; this.density = density; this.lifeTime = lifeTime; this.prewarm = prewarm; this.isAutoOrient = isAutoOrient; this.particleRotation = particleRotation; (this as IHaveParticles).SetParticleSettings(prewarm, ParticleSystemSimulationSpace.Local, density, lifeTime, 0, 1, isAutoOrient, particleRotation); SetShape(); } #endregion } #region [轮询更新] Main Update public partial class ParticleTracker { private void Update() { float songTime = CoreServices.TimeProvider.SongTime; if (playTime > songTime || stopTime < songTime) { particle.Stop(); } else { if (!particle.isPlaying) { particle.Play(); } } } } #endregion #region [行为重写] Behavior Overrides public partial class ParticleTracker { private void SetShape() { particleController.is3D = is3D; particleController.width = width; particleController.extendDirection = extendDirection; particleController.Rebuild(); } public override void Refresh() { base.Refresh(); ParticleSystemRenderer particleSystemRenderer = particle.GetComponent(); particleSystemRenderer.material.SetColor("_BaseColor", colorSubmodule.currentBaseColor); if (colorSubmodule.emissionEnabled) { particleSystemRenderer.material.SetFloat("_EnableEmission", 1); particleSystemRenderer.material.SetColor("_EmissionColor", colorSubmodule.GetCurrentEmissionColor()); } else { particleSystemRenderer.material.SetFloat("_EnableEmission", 0); } } } #endregion }