啊啊啊FE你这需求真难做啊啊啊

This commit is contained in:
SoulliesOfficial
2025-07-03 18:14:17 -04:00
parent ffb97c6d28
commit 6533997d59
21 changed files with 22026 additions and 16139 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a51c4f27e68ef814390c1cbb84f208ef
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,247 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Dreamteck.Splines;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
using UnityEngine.Serialization;
namespace Ichni.RhythmGame
{
public partial class ParticleTracker : GameElement
{
public Track track;
public ParticleController particleController;
public ParticleSystem particle;
public float playTime;
public float stopTime;
public float width;
public float density;
public bool prewarm;
public bool isAutoOrient;
public Vector3 particleRotation;
public string themeBundleName;
public string materialName;
public static ParticleTracker GenerateElement(string elementName, Guid id, List<string> tags,
bool isFirstGenerated, Track track, string themeBundleName, string materialName,
float playTime, float stopTime,
float width, float density, bool prewarm, bool isAutoOrient, Vector3 particleRotation)
{
ParticleTracker particleTracker = Instantiate(EditorManager.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.themeBundleList = ThemeBundleManager.instance.loadedThemeBundleList.ConvertAll(x => x.themeBundleName);
particleTracker.materialNameList = new List<string>();
particleTracker.SetParticleMaterial(themeBundleName, materialName);
particleTracker.SetParticleSettings(width, density, prewarm, isAutoOrient, particleRotation);
return particleTracker;
}
public void SetParticleMaterial(string themeBundleName, string materialName)
{
Material material = ThemeBundleManager.instance.GetObject<Material>(themeBundleName, materialName) ??
EditorManager.instance.basePrefabs.defaultParticleMaterial;
particle.GetComponent<Renderer>().material = Instantiate(material);
}
public void SetParticleSettings(float width, float density, bool prewarm, bool isAutoOrient, Vector3 particleRotation)
{
this.width = width;
this.density = density;
this.prewarm = prewarm;
this.isAutoOrient = isAutoOrient;
this.particleRotation = particleRotation;
SetWidth();
SetDensity();
SetAlignment();
}
}
public partial class ParticleTracker
{
private void Update()
{
float songTime = EditorManager.instance.songInformation.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,
playTime, stopTime, width, density, prewarm, isAutoOrient, particleRotation,
themeBundleName, materialName);
}
private List<string> themeBundleList;
private List<string> materialNameList;
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Particle Tracker");
DynamicUISubcontainer particleSettings0 = container.GenerateSubcontainer(3);
inspector.GenerateInputField(this, particleSettings0, "Play Time", nameof(playTime));
inspector.GenerateInputField(this, particleSettings0, "Stop Time", nameof(stopTime));
inspector.GenerateInputField(this, particleSettings0, "Width", nameof(width)).AddListenerFunction(SetWidth);
inspector.GenerateInputField(this, particleSettings0, "Density", nameof(density)).AddListenerFunction(SetDensity);
inspector.GenerateToggle(this, particleSettings0, "Prewarm", nameof(prewarm)).AddListenerFunction(SetPrewarm);
inspector.GenerateToggle(this, particleSettings0, "Is Auto Orient", nameof(isAutoOrient)).AddListenerFunction(SetAlignment);
DynamicUISubcontainer particleSettings1 = container.GenerateSubcontainer(1);
inspector.GenerateVector3InputField(this, particleSettings1, "Particle Rotation", nameof(particleRotation)).AddListenerFunction(SetParticleRotation);
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_GameObject.ConvertAll(x => x.name);
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", materialNameList, nameof(materialName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
}
else
{
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", new List<string>(), nameof(materialName));
objectNameDropdown.dropdown.interactable = false;
} // 如果没有选择主题包,则材质名称下拉框不可用
var setMaterialButton = inspector.GenerateButton(this, materialSettings, "Set Material", () =>
{
SetParticleMaterial(themeBundleName, materialName);
});
if (themeBundleName == String.Empty || materialName == String.Empty)
{
setMaterialButton.button.interactable = false;
}
}
}
public partial class ParticleTracker
{
private void SetWidth()
{
particleController.width = width;
particleController.Rebuild();
}
private void SetDensity()
{
var emission = particle.emission;
emission.rateOverTime = density;
}
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;
}
}
namespace Beatmap
{
public class ParticleTracker_BM : GameElement_BM
{
public float playTime;
public float stopTime;
public float width;
public float density;
public bool prewarm;
public bool isAutoOrient;
public Vector3 particleRotation;
public string materialThemeBundleName;
public string materialName;
public ParticleTracker_BM()
{
}
public ParticleTracker_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM attachedElement,
float playTime, float stopTime,
float width, float density, bool prewarm, bool isAutoOrient, Vector3 particleRotation,
string materialThemeBundleName, string materialName)
: base(elementName, elementGuid, tags, attachedElement)
{
this.playTime = playTime;
this.stopTime = stopTime;
this.width = width;
this.density = density;
this.prewarm = prewarm;
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,
playTime, stopTime, width, density, prewarm, isAutoOrient, particleRotation);
}
public override GameElement DuplicateBM(GameElement attached)
{
return ParticleTracker.GenerateElement(
elementName, Guid.NewGuid(), tags, false, attached as Track,
materialThemeBundleName, materialName,
playTime, stopTime, width, density, prewarm, isAutoOrient, particleRotation);
}
}
}
}

View File

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

View File

@@ -162,6 +162,13 @@ namespace Ichni.RhythmGame
var flickButton = inspector.GenerateButton(this, noteSubcontainer, "Flick",
() => { Flick.GenerateElement("New Flick", Guid.NewGuid(), new List<string>(), true, this, 0f, new List<Vector2>()); }); //Note Flick
var particleSubcontainer = generateContainer.GenerateSubcontainer(3);
var particleTrackerButton = inspector.GenerateButton(this, particleSubcontainer, "Particle Tracker",
() => { ParticleTracker.GenerateElement("New Particle Tracker", Guid.NewGuid(), new List<string>(), true, this,
string.Empty, string.Empty, 0, 1, 10, 10, true, true, Vector3.zero); }); //Particle Tracker
StandardInspectionElement.GenerateForTransform(this, generateContainer); //关于有Transform的元素
// var animationSubcontainer = generateContainer.GenerateSubcontainer(3);
// var displacementButton = inspector.GenerateButton(this, animationSubcontainer, "Displacement", () =>

View File

@@ -134,7 +134,14 @@ namespace Ichni.RhythmGame
protected void SetEnableEmission()
{
meshRenderer.material.SetInt("_Emission", enableEmission ? 1 : 0);
if (enableEmission)
{
meshRenderer.material.EnableKeyword("_EMISSION_ON");
}
else
{
meshRenderer.material.DisableKeyword("_EMISSION_ON");
}
}
protected void SetEnableZWrite()