Files
ichni_Official/Assets/Scripts/Game/GameElements/Track/ParticleTracker/ParticleTracker.cs

257 lines
9.3 KiB
C#
Raw Normal View History

2025-07-10 08:42:30 -04:00
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, IHaveColorSubmodule
{
public Track track;
public ParticleController particleController;
public ParticleSystem particle;
public ColorSubmodule colorSubmodule { get; set; }
public bool haveBaseColor => true;
public bool haveEmissionColor => true;
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;
public static ParticleTracker GenerateElement(string elementName, Guid id, List<string> 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>();
particleTracker.Initialize(elementName, id, tags, isFirstGenerated, track);
particleTracker.track = track;
particleTracker.particleController.spline = track.trackPathSubmodule.path;
particleTracker.playTime = playTime;
particleTracker.stopTime = stopTime;
particleTracker.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);
}
public void SetParticleMaterial(string themeBundleName, string materialName)
{
Material material = ThemeBundleManager.instance.GetObject<Material>(themeBundleName, materialName) ??
GameManager.instance.basePrefabs.defaultParticleMaterial;
Renderer particleRenderer = particle.GetComponent<Renderer>();
2025-07-21 05:42:20 -04:00
particleRenderer.material = material;
2025-07-10 08:42:30 -04:00
particleRenderer.InitializeShader();
}
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;
SetPrewarm();
SetShape();
SetDensity();
SetLifeTime();
SetAlignment();
}
}
public partial class ParticleTracker
{
private void Update()
{
float songTime = GameManager.instance.songTime;
if (playTime > songTime || stopTime < songTime)
{
particle.Stop();
}
else
{
if (!particle.isPlaying)
{
particle.Play();
}
}
}
public override void SaveBM()
{
matchedBM = new ParticleTracker_BM(elementName, elementGuid, tags,
parentElement.matchedBM as GameElement_BM,
prewarm, playTime, stopTime, is3D, width, extendDirection, density, lifeTime, isAutoOrient, particleRotation,
themeBundleName, materialName);
}
}
public partial class ParticleTracker
{
private void SetShape()
{
particleController.is3D = is3D;
particleController.width = width;
particleController.extendDirection = extendDirection;
particleController.Rebuild();
}
private void SetDensity()
{
var emission = particle.emission;
emission.rateOverTime = density;
}
private void SetLifeTime()
{
var mainModule = particle.main;
mainModule.startLifetime = lifeTime;
}
private void SetPrewarm()
{
var mainModule = particle.main;
mainModule.prewarm = prewarm;
}
private void SetAlignment()
{
ParticleSystemRenderer particleSystemRenderer = particle.GetComponent<ParticleSystemRenderer>();
var mainModule = particle.main;
if (isAutoOrient)
{
particleSystemRenderer.alignment = ParticleSystemRenderSpace.View;
mainModule.startRotation3D = false; // 禁用3D旋转
}
else
{
particleSystemRenderer.alignment = ParticleSystemRenderSpace.Local;
mainModule.startRotation3D = true; // 启用3D旋转
SetParticleRotation();
}
}
private void SetParticleRotation()
{
var mainModule = particle.main;
mainModule.startRotationX = particleRotation.x;
mainModule.startRotationY = particleRotation.y;
mainModule.startRotationZ = particleRotation.z;
}
public override void Refresh()
{
base.Refresh();
ParticleSystemRenderer particleSystemRenderer = particle.GetComponent<ParticleSystemRenderer>();
particleSystemRenderer.material.SetColor("_BaseColor", colorSubmodule.currentBaseColor);
if (colorSubmodule.emissionEnabled)
{
particleSystemRenderer.material.EnableKeyword("_EMISSION_ON");
particleSystemRenderer.material.SetColor("_EmissionColor", colorSubmodule.GetCurrentEmissionColor());
}
else
{
particleSystemRenderer.material.DisableKeyword("_EMISSION_ON");
}
}
}
namespace Beatmap
{
public class ParticleTracker_BM : GameElement_BM
{
public bool prewarm = false;
public float playTime = 0f;
public float stopTime = 1f;
public bool is3D = false;
public float width = 10f;
public Vector3 extendDirection = Vector3.right;
public float density = 10;
public float lifeTime = 5;
public bool isAutoOrient = true;
public Vector3 particleRotation = Vector3.zero;
public string materialThemeBundleName = string.Empty;
public string materialName = string.Empty;
public ParticleTracker_BM()
{
}
public ParticleTracker_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM attachedElement,
bool prewarm, float playTime, float stopTime,
bool is3D, float width, Vector3 extendDirection,
float density, float lifeTime,
bool isAutoOrient, Vector3 particleRotation,
string materialThemeBundleName, string materialName) : base(elementName, elementGuid, tags, attachedElement)
{
this.prewarm = prewarm;
this.playTime = playTime;
this.stopTime = stopTime;
this.width = width;
this.density = density;
this.is3D = is3D;
this.extendDirection = extendDirection;
this.lifeTime = lifeTime;
this.isAutoOrient = isAutoOrient;
this.particleRotation = particleRotation;
this.materialThemeBundleName = materialThemeBundleName;
this.materialName = materialName;
}
public override void ExecuteBM()
{
matchedElement = ParticleTracker.GenerateElement(
elementName, elementGuid, tags, false,
GetElement(attachedElementGuid) as Track, materialThemeBundleName, materialName,
prewarm, playTime, stopTime, is3D, width, extendDirection, density, lifeTime, isAutoOrient, particleRotation);
}
public override GameElement DuplicateBM(GameElement attached)
{
return ParticleTracker.GenerateElement(
elementName, Guid.NewGuid(), tags, false,
attached as Track, materialThemeBundleName, materialName,
prewarm, playTime, stopTime, is3D, width, extendDirection, density, lifeTime, isAutoOrient, particleRotation);
}
}
}
}