小更新

This commit is contained in:
SoulliesOfficial
2025-08-22 12:05:09 -04:00
parent 2e4398b9c1
commit e119b32655
63 changed files with 463740 additions and 28841 deletions

View File

@@ -0,0 +1,360 @@
using System;
using System.Collections.Generic;
using Ichni.RhythmGame.Beatmap;
using Ichni.Editor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Ichni.RhythmGame
{
public partial class ParticleEmitter : GameElement, IHaveParticles, IHaveTimeDurationSubmodule, IHaveTransformSubmodule, IHaveColorSubmodule
{
public ParticleSystem particle { get; set; }
private IHaveParticles particlesContainer => this;
public TimeDurationSubmodule timeDurationSubmodule { get; set; }
public TransformSubmodule transformSubmodule { get; set; }
public ColorSubmodule colorSubmodule { get; set; }
public bool haveBaseColor => true;
public bool haveEmissionColor => true;
private List<string> themeBundleList;
private List<string> materialNameList;
public string themeBundleName;
public string materialName;
public bool prewarm;
public float playTime;
public float stopTime;
public ParticleSystemSimulationSpace simulationSpace;
public float density;
public float lifeTime;
public float speed;
public float radius;
public bool isAutoOrient;
public Vector3 particleRotation;
public static ParticleEmitter GenerateElement(string elementName, Guid id, List<string> tags,
bool isFirstGenerated, GameElement parentElement, string themeBundleName, string materialName,
bool prewarm, float playTime, float stopTime, ParticleSystemSimulationSpace simulationSpace,
float density, float lifeTime, float speed, float radius,
bool isAutoOrient, Vector3 particleRotation)
{
ParticleEmitter particleEmitter = Instantiate(EditorManager.instance.basePrefabs.particleEmitter, parentElement.transform)
.GetComponent<ParticleEmitter>();
particleEmitter.particle = particleEmitter.GetComponent<ParticleSystem>();
particleEmitter.Initialize(elementName, id, tags, isFirstGenerated, parentElement);
particleEmitter.playTime = playTime;
particleEmitter.stopTime = stopTime;
particleEmitter.themeBundleList = ThemeBundleManager.instance.loadedThemeBundleList.ConvertAll(x => x.themeBundleName);
particleEmitter.materialNameList = new List<string>();
particleEmitter.themeBundleName = themeBundleName;
particleEmitter.materialName = materialName;
particleEmitter.particlesContainer.SetParticleMaterial(themeBundleName, materialName);
particleEmitter.SetParticleSettings(prewarm, simulationSpace, density, lifeTime, speed, radius, isAutoOrient, particleRotation, false);
return particleEmitter;
}
public void SetParticleSettings(bool prewarm, ParticleSystemSimulationSpace simulationSpace,
float density, float lifeTime, float speed, float radius, bool isAutoOrient, Vector3 particleRotation, bool mark)
{
//这个Mark没有任何作用只是为了让解释器把interface中的函数和这个函数区分开。否则会Stackoverflow。
this.prewarm = prewarm;
this.simulationSpace = simulationSpace;
this.density = density;
this.lifeTime = lifeTime;
this.speed = speed;
this.radius = radius;
this.isAutoOrient = isAutoOrient;
this.particleRotation = particleRotation;
(this as IHaveParticles).SetParticleSettings(prewarm, simulationSpace, density, lifeTime, speed, radius, isAutoOrient, particleRotation);
}
public override void SetDefaultSubmodules()
{
timeDurationSubmodule = new TimeDurationSubmodule(this);
transformSubmodule = new TransformSubmodule(this);
colorSubmodule = new ColorSubmodule(this, Color.white, true, Color.white, 0);
}
}
public partial class ParticleEmitter
{
private void Update()
{
float songTime = EditorManager.instance.songInformation.songTime;
if (playTime > songTime || stopTime < songTime)
{
if (particle.isPlaying || particle.isPaused)
{
particle.Stop();
if (songTime < playTime) { particle.Clear(); }
}
}
else
{
if (!EditorManager.instance.musicPlayer.isPlaying)
{
particle.Pause();
}
else if (!particle.isPlaying)
{
particle.Play();
}
}
}
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");
}
}
}
public partial class ParticleEmitter
{
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Particle Tracker");
// 确保 themeBundleList 初始化
if (themeBundleList == null)
themeBundleList = ThemeBundleManager.instance.loadedThemeBundleList.ConvertAll(x => x.themeBundleName);
DynamicUISubcontainer particleSettings0 = container.GenerateSubcontainer(3);
inspector.GenerateToggle(this, particleSettings0, "Prewarm", nameof(prewarm))
.AddListenerFunction(() => particlesContainer.SetPrewarm(prewarm));
inspector.GenerateInputField(this, particleSettings0, "Play Time", nameof(playTime));
inspector.GenerateInputField(this, particleSettings0, "Stop Time", nameof(stopTime));
DynamicUISubcontainer particleSettings2 = container.GenerateSubcontainer(3);
inspector.GenerateDropdown(this, particleSettings2, "Simulation Space", typeof(ParticleSystemSimulationSpace), nameof(simulationSpace))
.AddListenerFunction(() => particlesContainer.SetSimulationSpace(simulationSpace));
inspector.GenerateInputField(this, particleSettings2, "Density", nameof(density))
.AddListenerFunction(()=>particlesContainer.SetDensity(density));
inspector.GenerateInputField(this, particleSettings2, "Life Time", nameof(lifeTime))
.AddListenerFunction(()=>particlesContainer.SetLifeTime(lifeTime));
inspector.GenerateInputField(this, particleSettings2, "Speed", nameof(speed))
.AddListenerFunction(()=>particlesContainer.SetSpeed(speed));
inspector.GenerateInputField(this, particleSettings2, "Radius", nameof(radius))
.AddListenerFunction(()=>particlesContainer.SetRadius(radius));
DynamicUISubcontainer particleSettings3_0 = container.GenerateSubcontainer(3);
inspector.GenerateToggle(this, particleSettings3_0, "Is Auto Orient", nameof(isAutoOrient))
.AddListenerFunction(()=>particlesContainer.SetAlignment(isAutoOrient, particleRotation));
DynamicUISubcontainer particleSettings3_1 = container.GenerateSubcontainer(1);
inspector.GenerateVector3InputField(this, particleSettings3_1, "Particle Rotation", nameof(particleRotation))
.AddListenerFunction(()=>particlesContainer.SetParticleRotation(particleRotation));
DynamicUISubcontainer materialSettings = container.GenerateSubcontainer(3);
var themeBundleDropdown =
inspector.GenerateDropdown(this, materialSettings, "Theme Bundle", themeBundleList, nameof(themeBundleName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
if (themeBundleName != String.Empty && ThemeBundleManager.instance.TryGetThemeBundle(themeBundleName, out ThemeBundle themeBundle))
{
materialNameList = themeBundle.assetList_Material.ConvertAll(x => x.name);
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", materialNameList, nameof(materialName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
}
else
{
materialNameList = new List<string>(); // 防止为null
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", materialNameList, nameof(materialName));
objectNameDropdown.dropdown.interactable = false;
} // 如果没有选择主题包,则材质名称下拉框不可用
var setMaterialButton = inspector.GenerateButton(this, materialSettings, "Set Material", () =>
{
particlesContainer.SetParticleMaterial(themeBundleName, materialName);
});
if (themeBundleName == String.Empty || materialName == String.Empty)
{
setMaterialButton.button.interactable = false;
}
}
public override void SaveBM()
{
matchedBM = new ParticleEmitter_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM,
prewarm, playTime, stopTime, simulationSpace, density, lifeTime, speed, radius,
isAutoOrient, particleRotation, themeBundleName, materialName);
}
}
namespace Beatmap
{
public class ParticleEmitter_BM : GameElement_BM
{
public bool prewarm = false;
public float playTime = 0f;
public float stopTime = 1f;
public ParticleSystemSimulationSpace simulationSpace;
public float density = 10;
public float lifeTime = 5;
public float speed;
public float radius;
public bool isAutoOrient = true;
public Vector3 particleRotation = Vector3.zero;
public string materialThemeBundleName = string.Empty;
public string materialName = string.Empty;
public ParticleEmitter_BM()
{
}
public ParticleEmitter_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM attachedElement,
bool prewarm, float playTime, float stopTime, ParticleSystemSimulationSpace simulationSpace,
float density, float lifeTime, float speed, float radius, bool isAutoOrient, Vector3 particleRotation,
string materialThemeBundleName, string materialName) :
base(elementName, elementGuid, tags, attachedElement)
{
this.prewarm = prewarm;
this.playTime = playTime;
this.stopTime = stopTime;
this.simulationSpace = simulationSpace;
this.density = density;
this.lifeTime = lifeTime;
this.speed = speed;
this.radius = radius;
this.isAutoOrient = isAutoOrient;
this.particleRotation = particleRotation;
this.materialThemeBundleName = materialThemeBundleName;
this.materialName = materialName;
}
public override void ExecuteBM()
{
matchedElement = ParticleEmitter.GenerateElement(elementName, elementGuid, tags, false,
GetElement(attachedElementGuid), materialThemeBundleName, materialName,
prewarm, playTime, stopTime, simulationSpace, density, lifeTime, speed, radius,
isAutoOrient, particleRotation);
}
public override GameElement DuplicateBM(GameElement attached)
{
return ParticleEmitter.GenerateElement(elementName, Guid.NewGuid(), tags, false,
attached, materialThemeBundleName, materialName,
prewarm, playTime, stopTime, simulationSpace, density, lifeTime, speed, radius,
isAutoOrient, particleRotation);
}
}
}
public interface IHaveParticles
{
public ParticleSystem particle { get; set; }
public virtual void SetParticleMaterial(string themeBundleName, string materialName)
{
Material material = ThemeBundleManager.instance.GetObject<Material>(themeBundleName, materialName);
if (material == null)
{
material = ThemeBundleManager.instance.GetObject<Material>("basic", "Basic_Track_Default");
}
Renderer particleRenderer = particle.GetComponent<Renderer>();
particleRenderer.material = Object.Instantiate(material);
particleRenderer.InitializeShader();
}
public virtual void SetParticleSettings(bool prewarm, ParticleSystemSimulationSpace simulationSpace, float density, float lifeTime,
float speed, float radius, bool isAutoOrient, Vector3 particleRotation)
{
SetPrewarm(prewarm);
SetSimulationSpace(simulationSpace);
SetDensity(density);
SetLifeTime(lifeTime);
SetSpeed(speed);
SetRadius(radius);
SetAlignment(isAutoOrient, particleRotation);
}
public void SetPrewarm(bool prewarm)
{
var mainModule = particle.main;
mainModule.prewarm = prewarm;
}
public void SetSimulationSpace(ParticleSystemSimulationSpace simulationSpace)
{
var mainModule = particle.main;
mainModule.simulationSpace = simulationSpace;
}
public void SetDensity(float density)
{
var emission = particle.emission;
emission.rateOverTime = density;
}
public void SetLifeTime(float lifeTime)
{
var mainModule = particle.main;
mainModule.startLifetime = lifeTime;
}
public void SetSpeed(float speed)
{
var mainModule = particle.main;
mainModule.startSpeed = speed;
}
public void SetRadius(float radius)
{
var shapeModule = particle.shape;
shapeModule.radius = radius;
}
public void SetAlignment(bool isAutoOrient, Vector3 particleRotation = default)
{
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(particleRotation);
}
}
public void SetParticleRotation(Vector3 particleRotation)
{
Vector3 vector3Rotation = particleRotation * Mathf.Deg2Rad;
var mainModule = particle.main;
mainModule.startRotationX = vector3Rotation.x;
mainModule.startRotationY = vector3Rotation.y;
mainModule.startRotationZ = vector3Rotation.z;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 169162a593e5d094b839ce348712fa85
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: