skybox subsetter

This commit is contained in:
SoulliesOfficial
2025-07-09 01:01:06 -04:00
parent 6533997d59
commit 537caabfa9
128 changed files with 13280 additions and 2268 deletions

View File

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

View File

@@ -0,0 +1,105 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame
{
public partial class CameraFieldOfView : AnimationBase
{
public FlexibleFloat fieldOfView;
public GameCamera targetGameCamera;
public static CameraFieldOfView GenerateElement(string elementName, Guid id,
List<string> tags, bool isFirstGenerated, GameCamera gameCamera, FlexibleFloat fieldOfView)
{
CameraFieldOfView camFOV = Instantiate(EditorManager.instance.basePrefabs.emptyObject)
.AddComponent<CameraFieldOfView>();
camFOV.Initialize(elementName, id, tags, isFirstGenerated, gameCamera);
camFOV.animatedObject = gameCamera;
camFOV.targetGameCamera = gameCamera;
camFOV.fieldOfView = fieldOfView;
camFOV.animationReturnType = FlexibleReturnType.Before;
return camFOV;
}
public override void SetDefaultSubmodules()
{
timeDurationSubmodule = new TimeDurationSubmodule(this);
}
protected override void UpdateAnimation(float songTime)
{
fieldOfView.UpdateFlexibleFloat(songTime);
if (fieldOfView.returnType == FlexibleReturnType.MiddleExecuting)
{
targetGameCamera.perspectiveAngle = fieldOfView.value;
targetGameCamera.gameCamera.fieldOfView = fieldOfView.value;
}
}
public override void ApplyTimeOffset(float offset)
{
base.ApplyTimeOffset(offset);
fieldOfView.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
}
}
public partial class CameraFieldOfView
{
public override void SaveBM()
{
matchedBM = new CameraFieldOfView_BM(elementName, elementGuid, tags, targetGameCamera.matchedBM as GameCamera_BM, fieldOfView.ConvertToBM());
}
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Camera Field of View");
var subcontainer = container.GenerateSubcontainer(3);
var fovButton = inspector.GenerateButton(this, subcontainer, "Field of View", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Field of View", nameof(fieldOfView)).SetAsFlexibleFloat();
});
}
}
namespace Beatmap
{
public partial class CameraFieldOfView_BM : AnimationBase_BM
{
public FlexibleFloat_BM fieldOfView;
public CameraFieldOfView_BM()
{
}
public CameraFieldOfView_BM(string elementName, Guid elementGuid, List<string> tags,
GameElement_BM attachedElement, FlexibleFloat_BM fieldOfView)
: base(elementName, elementGuid, tags, attachedElement)
{
this.fieldOfView = fieldOfView;
}
public override void ExecuteBM()
{
matchedElement = CameraFieldOfView.GenerateElement(elementName, elementGuid, tags, false,
GetElement(attachedElementGuid) as GameCamera, fieldOfView.ConvertToGameType());
}
public override GameElement DuplicateBM(GameElement parent)
{
return CameraFieldOfView.GenerateElement(elementName, Guid.NewGuid(), tags, false,
parent as GameCamera, fieldOfView.ConvertToGameType());
}
}
}
}

View File

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

View File

@@ -75,7 +75,7 @@ namespace Ichni.RhythmGame
namespace Beatmap
{
public class TrackTotalTimeChange_BM : GameElement_BM
public class TrackTotalTimeChange_BM : AnimationBase_BM
{
public FlexibleFloat_BM totalTime;

View File

@@ -107,15 +107,18 @@ namespace Ichni.RhythmGame
var container = inspector.GenerateContainer("Color");
var subcontainer = container.GenerateSubcontainer(1, 300f);
var baseColor = inspector.GenerateBaseColorPicker(this, subcontainer, "Base Color", nameof(originalBaseColor));
baseColor.AddListenerFunction(Refresh);
if (attachedGameElement.childElementList.Exists(x => x is BaseColorChange))
if ((attachedGameElement as IHaveColorSubmodule).haveBaseColor)
{
baseColor.title.text += " (Occupied by Animation)";
baseColor.canvasGroup.interactable = false;
var baseColor = inspector.GenerateBaseColorPicker(this, subcontainer, "Base Color", nameof(originalBaseColor));
baseColor.AddListenerFunction(Refresh);
if (attachedGameElement.childElementList.Exists(x => x is BaseColorChange))
{
baseColor.title.text += " (Occupied by Animation)";
baseColor.canvasGroup.interactable = false;
}
}
if ((attachedGameElement as IHaveColorSubmodule).haveEmission)
if ((attachedGameElement as IHaveColorSubmodule).haveEmissionColor)
{
var emissionColor = inspector.GenerateEmissionColorPicker(this, subcontainer, "Emission Color",
nameof(emissionEnabled), nameof(originalEmissionColor), nameof(originalEmissionIntensity));
@@ -142,7 +145,8 @@ namespace Ichni.RhythmGame
public interface IHaveColorSubmodule
{
public ColorSubmodule colorSubmodule { get; set; }
public bool haveEmission => false;
public virtual bool haveBaseColor => true;
public virtual bool haveEmissionColor => false;
public void SetColorObserver()
{

View File

@@ -133,6 +133,7 @@ namespace Ichni.RhythmGame
{ "Bloom", new BloomEffect(1, 2, CustomCurvePresets.Parabolic(1, 0, 1)) },
{ "CameraShake", new CameraShakeEffect(1, 50, 1, 1, 1) },
{ "CameraOffset", new CameraOffsetEffect(0.2f, Vector3.forward, CustomCurvePresets.CustomPeakTimeParabolic(1, 0, 1, 0.3f)) },
{ "CameraZoom", new CameraZoomEffect(0.2f, 5f,CustomCurvePresets.Parabolic(1,0,1))},
{ "CameraTilt", new CameraTiltEffect(0.2f, new Vector3(0, 0, 5), CustomCurvePresets.CustomPeakTimeParabolic(1, 0, 1, 0.3f)) },
{ "ChromaticAberration", new ChromaticAberrationEffect(1, 1, CustomCurvePresets.Parabolic(1, 0, 1)) },
{ "Vignette", new VignetteEffect(1, 1, 0.4f, Color.black, CustomCurvePresets.Parabolic(1, 0, 1)) },

View File

@@ -13,6 +13,7 @@ namespace Ichni.RhythmGame
public float bpm; //每分钟节拍数
public float delay; //设定音乐和谱面延迟Delay秒后开始在延迟中SongPosition为负数。
public float songLength;
public float songTime;
public float songBeat => songTime / 60 * bpm;
@@ -25,7 +26,18 @@ namespace Ichni.RhythmGame
this.delay = delay;
songLocation = EditorManager.instance.projectInformation.projectPath + "/" + songName;
Debug.Log("Loading song from " + songLocation + " " + ES3.FileExists(songLocation));
song = ES3.LoadAudio(songLocation, AudioType.WAV);
string extension = System.IO.Path.GetExtension(songLocation).ToLower();
song = extension switch
{
".mp3" => ES3.LoadAudio(songLocation, AudioType.MPEG),
".ogg" => ES3.LoadAudio(songLocation, AudioType.OGGVORBIS),
".wav" => ES3.LoadAudio(songLocation, AudioType.WAV),
_ => throw new System.Exception("Unsupported audio format: " + extension)
};
songLength = song.length;
}
public void SaveBM()

View File

@@ -53,7 +53,7 @@ namespace Ichni.RhythmGame
var generateBaseColorChangeButton = inspector.GenerateButton(this, generateAnimation, "Base Color Change",
() => BaseColorChange.GenerateElement("New Base Color Change", Guid.NewGuid(), new List<string>(), true,
this, new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat()));
if (haveEmission)
if (haveEmissionColor)
{
var generateEmissionColorChangeButton = inspector.GenerateButton(this, generateAnimation, "Emission Color Change",
() => EmissionColorChange.GenerateElement("New Emission Color Change", Guid.NewGuid(), new List<string>(), true,

View File

@@ -71,7 +71,9 @@ namespace Ichni.RhythmGame
StandardInspectionElement.GenerateForTransform(this, container); //关于有Transform的元素
var generateAnimation = container.GenerateSubcontainer(3);
var fovAnimationButton = inspector.GenerateButton(this, generateAnimation, "Field of View",
() => CameraFieldOfView.GenerateElement("New Field of View", Guid.NewGuid(),
new List<string>(), true, this, new FlexibleFloat()));
var extensionButton = inspector.GenerateButton(this, generateAnimation, "Extension",
() => GameCameraExtension.GenerateElement("New Extension", Guid.NewGuid(),
new List<string>(), true, this, 1000f));

View File

@@ -0,0 +1,83 @@
using System.Collections;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using Lean.Pool;
using MoreMountains.Feedbacks;
using UnityEngine;
namespace Ichni.RhythmGame
{
public class CameraZoomEffect : EffectBase
{
public float duration;
public float relativeZoom;
public AnimationCurve zoomCurve;
Camera gameCamera => EditorManager.instance.cameraManager.gameCamera.gameCamera;
public CameraZoomEffect(float duration, float relativeZoom, AnimationCurve zoomCurve)
{
this.effectTime = 0f;
this.duration = duration;
this.relativeZoom = relativeZoom;
this.zoomCurve = zoomCurve;
}
public override void Adjust()
{
MMF_Player effect = LeanPool.Spawn(EditorManager.instance.basePrefabs.cameraZoomEffect).GetComponent<MMF_Player>();
effect.GetFeedbackOfType<MMF_CameraFieldOfView>().Duration = duration;
effect.GetFeedbackOfType<MMF_CameraFieldOfView>().RemapFieldOfViewOne = relativeZoom;
effect.GetFeedbackOfType<MMF_CameraFieldOfView>().ShakeFieldOfView = zoomCurve;
effect.PlayFeedbacks();
LeanPool.Despawn(effect.gameObject, duration);
}
public override EffectBase_BM ConvertToBM()
{
return new Beatmap.CameraZoomEffect_BM(duration, relativeZoom, zoomCurve);
}
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Camera Shake");
var effectSettings = container.GenerateSubcontainer(3);
var zoomDurationInputField = inspector.GenerateInputField(this, effectSettings, "Zoom Duration", nameof(duration));
var relativeZoomInputField = inspector.GenerateInputField(this, effectSettings, "Relative Zoom", nameof(relativeZoom));
var zoomCurveButton = inspector.GenerateButton(this, effectSettings, "Intensity Curve", () =>
{
var zoomCurveWindow =
inspector.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(zoomCurve)).SetAsCustomCurve();
});
}
}
namespace Beatmap
{
public class CameraZoomEffect_BM : EffectBase_BM
{
public float duration;
public float relativeZoom;
public AnimationCurve zoomCurve;
public CameraZoomEffect_BM()
{
}
public CameraZoomEffect_BM(float duration, float relativeZoom, AnimationCurve zoomCurve)
{
this.duration = duration;
this.relativeZoom = relativeZoom;
this.zoomCurve = zoomCurve;
}
public override EffectBase ConvertToGameType(GameElement attachedGameElement)
{
return new CameraZoomEffect(duration, relativeZoom, zoomCurve);
}
}
}
}

View File

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

View File

@@ -4,6 +4,7 @@ using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
using UnityEngine.Serialization;
namespace Ichni.RhythmGame
{
@@ -15,6 +16,8 @@ namespace Ichni.RhythmGame
public Material skyboxMaterial;
public string backgroundSpriteName;
public Sprite backgroundSprite;
[FormerlySerializedAs("skyboxController")] public SkyboxSubsetter skyboxSubsetter;
public static BackgroundSetter GenerateElement(string elementName, Guid id, List<string> tags,
bool isFirstGenerated, GameElement parentElement, bool useSkybox, string skyboxThemeBundleName,
@@ -36,10 +39,11 @@ namespace Ichni.RhythmGame
backgroundSetter.backgroundSpriteName = backgroundSpriteName;
return backgroundSetter;
}
public override void Refresh()
{
EditorManager.instance.backgroundController.EnableBackground(!useSkybox);
if (useSkybox)
if (useSkybox && skyboxSubsetter == null)
{
SetSkybox(skyboxThemeBundleName, skyboxMaterialName);
}
@@ -80,6 +84,21 @@ namespace Ichni.RhythmGame
useSkyboxToggle.AddListenerFunction(() => EditorManager.instance.backgroundController.EnableBackground(!useSkybox));
useSkyboxToggle.AddListenerFunction(() => SetInputFields(useSkybox));
var generateContainer = inspector.GenerateContainer("Generate");
var generateSubContainer = generateContainer.GenerateSubcontainer(3);
var generateSkyboxControllerButton = inspector.GenerateButton(this, generateSubContainer, "Skybox Controller", () =>
{
if (skyboxSubsetter == null)
{
SkyboxSubsetter.GenerateElement("New Skybox Subsetter", Guid.NewGuid(), new List<string>(), true, this,
new List<string>(), new List<string>(), new List<float>(), new List<float>());
}
else
{
LogWindow.Log("There is already a Skybox Subsetter in the scene.", Color.yellow);
}
});
}
}

View File

@@ -0,0 +1,200 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
using UnityEngine.Serialization;
using Object = UnityEngine.Object;
namespace Ichni.RhythmGame
{
public partial class SkyboxSubsetter : GameElement
{
public SkyboxBlender skyboxBlender;
public List<string> skyBoxThemeBundleList;
public List<string> skyboxNameList;
public List<Material> skyboxMaterialList;
public List<float> blendSpeedList;
public List<float> blendTimeList;
public int currentSkyboxIndex = 0;
public List<string> themeBundleListForSelection;
public List<string> skyboxNameListForSelection;
public string selectedThemeBundle;
public string selectedSkybox;
public static SkyboxSubsetter GenerateElement(string elementName, Guid id, List<string> tags,
bool isFirstGenerated, GameElement parentElement, List<string> themeBundleList,List<string> skyboxList,
List<float> blendTimeList, List<float> blendSpeedList)
{
SkyboxSubsetter skyboxSubsetter = Instantiate(EditorManager.instance.basePrefabs.emptyObject)
.AddComponent<SkyboxSubsetter>();
EditorManager.instance.backgroundSetter.skyboxSubsetter = skyboxSubsetter;
skyboxSubsetter.Initialize(elementName, id, tags, isFirstGenerated, parentElement);
skyboxSubsetter.skyBoxThemeBundleList = themeBundleList;
skyboxSubsetter.skyboxNameList = skyboxList;
skyboxSubsetter.skyboxMaterialList = new List<Material>();
skyboxSubsetter.blendTimeList = blendTimeList;
skyboxSubsetter.blendSpeedList = blendSpeedList;
skyboxSubsetter.SetUpBlender();
skyboxSubsetter.themeBundleListForSelection = ThemeBundleManager.instance.loadedThemeBundleList.ConvertAll(x => x.themeBundleName);
skyboxSubsetter.skyboxNameListForSelection = new List<string>();
skyboxSubsetter.selectedThemeBundle = String.Empty;
skyboxSubsetter.selectedSkybox = String.Empty;
return skyboxSubsetter;
}
private void SetUpBlender()
{
skyboxBlender = gameObject.AddComponent<SkyboxBlender>();
skyboxBlender.loop = false;
skyboxBlender.timeToWait = 0f;
skyboxBlender.updateLighting = false;
skyboxBlender.updateReflections = false;
skyboxBlender.skyboxMaterials = new List<Material>();
for (int i = 0; i < skyBoxThemeBundleList.Count; i++)
{
Material skybox = ThemeBundleManager.instance.GetObject<Material>(skyBoxThemeBundleList[i], skyboxNameList[i]);
skyboxMaterialList.Add(skybox);
skyboxBlender.skyboxMaterials.Add(skybox);
}
skyboxBlender.makeFirstMaterialSkybox = true;
skyboxBlender.InspectorAndAwakeChanges();
}
private void AddSkybox(string skyboxThemeBundleName, string skyboxObjectName)
{
Material skybox = ThemeBundleManager.instance.GetObject<Material>(skyboxThemeBundleName, skyboxObjectName);
if (skybox != null)
{
skyBoxThemeBundleList.Add(skyboxThemeBundleName);
skyboxNameList.Add(skyboxObjectName);
skyboxMaterialList.Add(skybox);
skyboxBlender.skyboxMaterials.Add(skybox);
}
}
private void Update()
{
if (skyBoxThemeBundleList.Count > 1)
{
float songTime = EditorManager.instance.songInformation.songTime;
float delay = EditorManager.instance.songInformation.delay;
float finalTime = EditorManager.instance.songInformation.songLength;
for (var index = 0; index < blendTimeList.Count + 1; index++)
{
float startTime = index == 0 ? -delay : blendTimeList[index - 1];
float endTime = index >= blendTimeList.Count ? finalTime : blendTimeList[index];
if(songTime >= startTime && songTime < endTime && currentSkyboxIndex != index)
{
currentSkyboxIndex = index;
if(currentSkyboxIndex != 0) skyboxBlender.blendSpeed = blendSpeedList[currentSkyboxIndex - 1];
skyboxBlender.Blend(currentSkyboxIndex, false);
DynamicGI.UpdateEnvironment();
}
}
}
}
public override void SaveBM()
{
matchedBM = new SkyboxSubsetter_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM,
skyBoxThemeBundleList, skyboxNameList, blendTimeList, blendSpeedList);
}
}
public partial class SkyboxSubsetter
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Skybox Subsetter");
DynamicUISubcontainer mainSettings = container.GenerateSubcontainer(3);
var blendSpeedListButton = inspector.GenerateButton(this, mainSettings, "Blend Speed List", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Blend Speed List", nameof(blendSpeedList))
.SetAsFloatList();
});
var blendTimeListButton = inspector.GenerateButton(this, mainSettings, "Blend Time List", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Blend Time List", nameof(blendTimeList))
.SetAsFloatList();
});
DynamicUISubcontainer materialSettings = container.GenerateSubcontainer(3);
Debug.Log((mainSettings == null) + " " + (themeBundleListForSelection == null) + " " + (selectedThemeBundle == null));
var themeBundleDropdown =
inspector.GenerateDropdown(this, materialSettings, "Theme Bundle", themeBundleListForSelection, nameof(selectedThemeBundle))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
if (selectedThemeBundle != String.Empty && ThemeBundleManager.instance.TryGetThemeBundle(selectedThemeBundle, out ThemeBundle themeBundle))
{
skyboxNameListForSelection = themeBundle.assetList_Material.ConvertAll(x => x.name);
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", skyboxNameListForSelection, nameof(selectedSkybox))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
}
else
{
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", new List<string>(), nameof(selectedSkybox));
objectNameDropdown.dropdown.interactable = false;
} // 如果没有选择主题包,则材质名称下拉框不可用
var setMaterialButton = inspector.GenerateButton(this, materialSettings, "Add Skybox", () =>
{
AddSkybox(selectedThemeBundle, selectedSkybox);
});
if (selectedThemeBundle == String.Empty || selectedSkybox == String.Empty)
{
setMaterialButton.button.interactable = false;
}
}
}
namespace Beatmap
{
public class SkyboxSubsetter_BM : GameElement_BM
{
public List<string> skyBoxThemeBundleList;
public List<string> skyboxNameList;
public List<float> blendTimeList;
public List<float> blendSpeedList;
public SkyboxSubsetter_BM()
{
}
public SkyboxSubsetter_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM attachedElement,
List<string> skyBoxThemeBundleList, List<string> skyboxNameList, List<float> blendTimeList, List<float> blendSpeedList)
: base(elementName, elementGuid, tags, attachedElement)
{
this.skyBoxThemeBundleList = skyBoxThemeBundleList;
this.skyboxNameList = skyboxNameList;
this.blendTimeList = blendTimeList;
this.blendSpeedList = blendSpeedList;
}
public override void ExecuteBM()
{
matchedElement = SkyboxSubsetter.GenerateElement(elementName, elementGuid, tags, false,
GetElement(attachedElementGuid), skyBoxThemeBundleList, skyboxNameList, blendTimeList, blendSpeedList);
}
public override GameElement DuplicateBM(GameElement attached)
{
return SkyboxSubsetter.GenerateElement(elementName, Guid.NewGuid(), tags, false,
attached, skyBoxThemeBundleList, skyboxNameList, blendTimeList, blendSpeedList);
}
}
}
}

View File

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

View File

@@ -13,7 +13,7 @@ namespace Ichni.RhythmGame
public TransformSubmodule transformSubmodule { get; set; }
public TimeDurationSubmodule timeDurationSubmodule { get; set; }
public ColorSubmodule colorSubmodule { get; set; }
public virtual bool haveEmission => false;
public virtual bool haveEmissionColor => false;
public static SubstantialObject GenerateElement(string elementName, Guid id, List<string> tags, bool isFirstGenerated,
string themeBundleName, string objectName, GameElement parentElement)

View File

@@ -9,27 +9,39 @@ using UnityEngine.Serialization;
namespace Ichni.RhythmGame
{
public partial class ParticleTracker : GameElement
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 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 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,
float playTime, float stopTime,
float width, float density, bool prewarm, bool isAutoOrient, Vector3 particleRotation)
bool prewarm, float playTime, float stopTime,
bool is3D, float width, Vector3 extendDirection,
float density, float lifeTime,
bool isAutoOrient, Vector3 particleRotation)
{
ParticleTracker particleTracker = Instantiate(EditorManager.instance.basePrefabs.particleTracker, track.transform)
.GetComponent<ParticleTracker>();
@@ -41,27 +53,43 @@ namespace Ichni.RhythmGame
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);
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) ??
EditorManager.instance.basePrefabs.defaultParticleMaterial;
particle.GetComponent<Renderer>().material = Instantiate(material);
Renderer particleRenderer = particle.GetComponent<Renderer>();
particleRenderer.material = Instantiate(material);
particleRenderer.InitializeShader();
}
public void SetParticleSettings(float width, float density, bool prewarm, bool isAutoOrient, Vector3 particleRotation)
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;
SetWidth();
SetShape();
SetDensity();
SetLifeTime();
SetAlignment();
}
}
@@ -88,7 +116,7 @@ namespace Ichni.RhythmGame
{
matchedBM = new ParticleTracker_BM(elementName, elementGuid, tags,
parentElement.matchedBM as GameElement_BM,
playTime, stopTime, width, density, prewarm, isAutoOrient, particleRotation,
prewarm, playTime, stopTime, is3D, width, extendDirection, density, lifeTime, isAutoOrient, particleRotation,
themeBundleName, materialName);
}
@@ -97,22 +125,31 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.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.GenerateToggle(this, particleSettings0, "Prewarm", nameof(prewarm)).AddListenerFunction(SetPrewarm);
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_0 = container.GenerateSubcontainer(3);
inspector.GenerateToggle(this, particleSettings1_0, "Is 3D", nameof(is3D)).AddListenerFunction(SetShape);
inspector.GenerateInputField(this, particleSettings1_0, "Width", nameof(width)).AddListenerFunction(SetShape);
DynamicUISubcontainer particleSettings1_1 = container.GenerateSubcontainer(1);
inspector.GenerateVector3InputField(this, particleSettings1_1, "Extend Direction", nameof(extendDirection)).AddListenerFunction(SetShape);
DynamicUISubcontainer particleSettings1 = container.GenerateSubcontainer(1);
inspector.GenerateVector3InputField(this, particleSettings1, "Particle Rotation", nameof(particleRotation)).AddListenerFunction(SetParticleRotation);
DynamicUISubcontainer particleSettings2 = container.GenerateSubcontainer(3);
inspector.GenerateInputField(this, particleSettings2, "Density", nameof(density)).AddListenerFunction(SetDensity);
inspector.GenerateInputField(this, particleSettings2, "Life Time", nameof(lifeTime)).AddListenerFunction(SetLifeTime);
DynamicUISubcontainer particleSettings3_0 = container.GenerateSubcontainer(3);
inspector.GenerateToggle(this, particleSettings3_0, "Is Auto Orient", nameof(isAutoOrient)).AddListenerFunction(SetAlignment);
DynamicUISubcontainer particleSettings3_1 = container.GenerateSubcontainer(1);
inspector.GenerateVector3InputField(this, particleSettings3_1, "Particle Rotation", nameof(particleRotation)).AddListenerFunction(SetParticleRotation);
DynamicUISubcontainer materialSettings = container.GenerateSubcontainer(3);
var themeBundleDropdown =
@@ -120,7 +157,7 @@ namespace Ichni.RhythmGame
.AddListenerFunction(() => inspectorMain.SetInspector(this));
if (themeBundleName != String.Empty && ThemeBundleManager.instance.TryGetThemeBundle(themeBundleName, out ThemeBundle themeBundle))
{
materialNameList = themeBundle.assetList_GameObject.ConvertAll(x => x.name);
materialNameList = themeBundle.assetList_Material.ConvertAll(x => x.name);
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", materialNameList, nameof(materialName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
@@ -146,9 +183,11 @@ namespace Ichni.RhythmGame
public partial class ParticleTracker
{
private void SetWidth()
private void SetShape()
{
particleController.is3D = is3D;
particleController.width = width;
particleController.extendDirection = extendDirection;
particleController.Rebuild();
}
@@ -158,6 +197,12 @@ namespace Ichni.RhythmGame
emission.rateOverTime = density;
}
private void SetLifeTime()
{
var mainModule = particle.main;
mainModule.startLifetime = lifeTime;
}
private void SetPrewarm()
{
var mainModule = particle.main;
@@ -188,21 +233,44 @@ namespace Ichni.RhythmGame
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 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 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()
{
@@ -210,18 +278,23 @@ namespace Ichni.RhythmGame
}
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)
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.prewarm = prewarm;
this.is3D = is3D;
this.extendDirection = extendDirection;
this.lifeTime = lifeTime;
this.isAutoOrient = isAutoOrient;
this.particleRotation = particleRotation;
this.materialThemeBundleName = materialThemeBundleName;
this.materialName = materialName;
}
@@ -230,17 +303,16 @@ namespace Ichni.RhythmGame
{
matchedElement = ParticleTracker.GenerateElement(
elementName, elementGuid, tags, false,
GetElement(attachedElementGuid) as Track,
materialThemeBundleName, materialName,
playTime, stopTime, width, density, prewarm, isAutoOrient, particleRotation);
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,
playTime, stopTime, width, density, prewarm, isAutoOrient, particleRotation);
elementName, Guid.NewGuid(), tags, false,
attached as Track, materialThemeBundleName, materialName,
prewarm, playTime, stopTime, is3D, width, extendDirection, density, lifeTime, isAutoOrient, particleRotation);
}
}
}

View File

@@ -19,7 +19,7 @@ namespace Ichni.RhythmGame
public TransformSubmodule transformSubmodule { get; set; }
public TimeDurationSubmodule timeDurationSubmodule { get; set; }
public ColorSubmodule colorSubmodule { get; set; }
public bool haveEmission => false;
public bool haveEmissionColor => false;
public override int HierarchyPriority => -100;
[Title("Editor独有参数")]

View File

@@ -167,7 +167,7 @@ namespace Ichni.RhythmGame
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
string.Empty, string.Empty, false, 0, 1, false, 10, Vector3.right, 10, 5, true, Vector3.zero); }); //Particle Tracker
StandardInspectionElement.GenerateForTransform(this, generateContainer); //关于有Transform的元素
// var animationSubcontainer = generateContainer.GenerateSubcontainer(3);