变量模块;Element启用控制

This commit is contained in:
SoulliesOfficial
2025-03-20 19:30:42 -04:00
parent ab86d6d985
commit 54de98b0fa
26 changed files with 1976 additions and 44 deletions

View File

@@ -20,9 +20,11 @@ namespace Ichni.RhythmGame
{
effectCollection = new Dictionary<string, List<EffectBase>>();
if (preset == EffectSubmodulePreset.Default) //对于默认的效果次级模块,只有Default效果集合
if (preset == EffectSubmodulePreset.Default) //对于默认的效果次级模块,有Prior、Default、Late三个效果集合
{
effectCollection.Add("Prior", new List<EffectBase>());
effectCollection.Add("Default", new List<EffectBase>());
effectCollection.Add("Late", new List<EffectBase>());
}
else if (preset == EffectSubmodulePreset.Note) //对于Note的效果次级模块在Note的不同状态下有独立的效果集合
{
@@ -33,6 +35,7 @@ namespace Ichni.RhythmGame
effectCollection.Add("Good", new List<EffectBase>());
effectCollection.Add("Bad", new List<EffectBase>());
effectCollection.Add("Miss", new List<EffectBase>());
effectCollection.Add("AfterJudge", new List<EffectBase>());
}
(attachedGameElement as IHaveEffectSubmodule).effectSubmodule = this;
@@ -79,7 +82,7 @@ namespace Ichni.RhythmGame
var effectNameInputField = inspector.GenerateInputField(container, "Effect Name");
var addEffectButton = inspector.GenerateButton(this, container, "Add Effect", () =>
{
if (EffectSubmodule.EffectCollection.TryGetValue(effectNameInputField.GetValue<string>(), out var newEffect))
if (EffectCollection.TryGetValue(effectNameInputField.GetValue<string>(), out var newEffect))
{
effectCollection[effect.Key].Add(newEffect);
inspectorMain.SetInspector(attachedGameElement);
@@ -107,7 +110,9 @@ namespace Ichni.RhythmGame
{ "Bloom", new BloomEffect(1, 2, CustomCurvePresets.Parabolic(1,0,2)) },
{ "CameraShake", new CameraShakeEffect(1, 50, 1, 1, 1) },
{ "ChromaticAberration", new ChromaticAberrationEffect(1, 1, CustomCurvePresets.Parabolic(1,0,1)) },
{ "Vignette", new VignetteEffect(1, 1, 0.4f, Color.black, CustomCurvePresets.Parabolic(1,0,1)) }
{ "Vignette", new VignetteEffect(1, 1, 0.4f, Color.black, CustomCurvePresets.Parabolic(1,0,1)) },
{ "SetInteger", new SetIntegerEffect("New Variable", 0, false, 0, 1) },
{ "EnableControl", new EnableControlEffect(null, "New Variable", 0, false, "") },
};
}

View File

@@ -0,0 +1,124 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame
{
public class EnableControlEffect : EffectBase
{
public GameElement connectedGameElement;
public string connectedVariableName;
public int enableValue;
public bool useExpression;
public string expression;
public EnableControlEffect(GameElement connectedGameElement, string connectedVariableName,
int enableValue, bool useExpression, string expression)
{
this.effectTime = 0;
this.connectedGameElement = connectedGameElement;
this.connectedVariableName = connectedVariableName;
this.enableValue = enableValue;
this.useExpression = useExpression;
this.expression = expression;
}
public override void Recover()
{
if (connectedGameElement == null) return;
connectedGameElement.gameObject.SetActive(false);
}
public override void Adjust()
{
if (connectedGameElement == null) return;
if (!useExpression)
{
int value = EditorManager.instance.variablesContainer.GetVariable(connectedVariableName);
connectedGameElement.gameObject.SetActive(value == enableValue);
}
else
{
}
}
public override EffectBase_BM ConvertToBM()
{
return new EnableControlEffect_BM(connectedGameElement.elementGuid,
connectedVariableName, enableValue, useExpression, expression);
}
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Enable Control");
var connectedGameElementInputField = inspector.GenerateInputField(container, "Game Element Name");
var connectGameElementButton = inspector.GenerateButton(this, container, "Connect Game Element", () =>
{
connectedGameElement = EditorManager.instance.beatmapContainer.gameElementList
.First(e => e.elementName == connectedGameElementInputField.GetValue<string>());
if (connectedGameElement == null)
{
LogWindow.Log("Game Element not found.", Color.red);
}
inspectorMain.SetInspector(EditorManager.instance.operationManager.currentSelectedElement);
});
string ShowConnection() => connectedGameElement == null ? "No Game Element Connected" : "Connected With: " + connectedGameElement.elementName;
var connectHintText = inspector.GenerateHintText(this, container, ShowConnection);
var connectedVariableNameInputField = inspector.GenerateInputField(this, container, "Connected Variable Name", nameof(connectedVariableName));
var enableValueInputField = inspector.GenerateInputField(this, container, "Enable Value", nameof(enableValue));
var useExpressionToggle = inspector.GenerateToggle(this, container, "Use Expression", nameof(useExpression));
useExpressionToggle.toggle.interactable = false;
var expressionInputField = inspector.GenerateInputField(this, container, "Expression", nameof(expression));
expressionInputField.inputField.interactable = false;
}
}
namespace Beatmap
{
public class EnableControlEffect_BM : EffectBase_BM
{
public Guid connectedGameElementGuid;
public string connectedVariableName;
public int enableValue;
public bool useExpression;
public string expression;
public EnableControlEffect_BM()
{
}
public EnableControlEffect_BM(Guid connectedGameElementGuid, string connectedVariableName,
int enableValue, bool useExpression, string expression)
{
this.connectedGameElementGuid = connectedGameElementGuid;
this.connectedVariableName = connectedVariableName;
this.enableValue = enableValue;
this.useExpression = useExpression;
this.expression = expression;
}
public override EffectBase ConvertToGameType(GameElement attachedGameElement)
{
return new EnableControlEffect(GameElement_BM.GetElement(connectedGameElementGuid), connectedVariableName,
enableValue, useExpression, expression);
}
}
}
}

View File

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

View File

@@ -0,0 +1,87 @@
using System.Collections;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame
{
public class SetIntegerEffect : EffectBase
{
public string targetVariableName;
public int targetValue;
public bool isRandom;
public int minValue;
public int maxValue;
public SetIntegerEffect(string targetVariableName, int targetValue, bool isRandom, int minValue, int maxValue)
{
this.effectTime = 0;
this.targetVariableName = targetVariableName;
this.targetValue = targetValue;
this.isRandom = isRandom;
this.minValue = minValue;
this.maxValue = maxValue;
}
public override void Recover()
{
EditorManager.instance.variablesContainer.RevertVariable(targetVariableName);
}
public override void Adjust()
{
EditorManager.instance.variablesContainer.SetVariable(targetVariableName, isRandom ? Random.Range(minValue, maxValue + 1) : targetValue);
}
public override EffectBase_BM ConvertToBM()
{
return new SetIntegerEffect_BM(targetVariableName, targetValue, isRandom, minValue, maxValue);
}
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Set Integer");
var targetVariableNameInputField = inspector.GenerateInputField(this, container, "Target Variable Name", nameof(targetVariableName));
var targetValueInputField = inspector.GenerateInputField(this, container, "Target Value", nameof(targetValue));
var isRandomToggle = inspector.GenerateToggle(this, container, "Is Random", nameof(isRandom));
var minValueInputField = inspector.GenerateInputField(this, container, "Min Value", nameof(minValue));
var maxValueInputField = inspector.GenerateInputField(this, container, "Max Value", nameof(maxValue));
}
}
namespace Beatmap
{
public class SetIntegerEffect_BM : EffectBase_BM
{
public string targetVariableName;
public int targetValue;
public bool isRandom;
public int minValue;
public int maxValue;
public SetIntegerEffect_BM()
{
}
public SetIntegerEffect_BM(string targetVariableName, int targetValue, bool isRandom, int minValue, int maxValue)
{
this.effectTime = 0;
this.targetVariableName = targetVariableName;
this.targetValue = targetValue;
this.isRandom = isRandom;
this.minValue = minValue;
this.maxValue = maxValue;
}
public override EffectBase ConvertToGameType(GameElement attachedGameElement)
{
return new SetIntegerEffect(targetVariableName, targetValue, isRandom, minValue, maxValue);
}
}
}
}

View File

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

View File

@@ -30,6 +30,7 @@ namespace Ichni.RhythmGame
private void Update()
{
effectSubmodule.effectCollection["Prior"].ForEach(effect => effect.UpdateEffect(time));
effectSubmodule.effectCollection["Default"].ForEach(effect => effect.UpdateEffect(time));
}
}

View File

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

View File

@@ -1,11 +1,11 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.Editor
namespace Ichni.RhythmGame
{
public partial class BackgroundSetter : GameElement
{
@@ -20,8 +20,15 @@ namespace Ichni.Editor
bool isFirstGenerated, GameElement parentElement, bool useSkybox, string skyboxThemeBundleName,
string skyboxMaterialName, string backgroundSpriteName)
{
if (EditorManager.instance.backgroundSetter != null)
{
LogWindow.Log("There is already a Background Setter in the scene.", Color.red);
return null;
}
BackgroundSetter backgroundSetter = Instantiate(EditorManager.instance.basePrefabs.emptyObject)
.AddComponent<BackgroundSetter>();
EditorManager.instance.backgroundSetter = backgroundSetter;
backgroundSetter.Initialize(elementName, id, tags, isFirstGenerated, parentElement);
backgroundSetter.useSkybox = useSkybox;
backgroundSetter.skyboxThemeBundleName = skyboxThemeBundleName;
@@ -29,26 +36,26 @@ namespace Ichni.Editor
backgroundSetter.backgroundSpriteName = backgroundSpriteName;
return backgroundSetter;
}
public void SetSkybox(string themeBundleName, string materialName)
public override void Refresh()
{
skyboxThemeBundleName = themeBundleName;
skyboxMaterialName = materialName;
skyboxMaterial = ThemeBundleManager.instance.GetObject<Material>(themeBundleName, materialName);
if (skyboxMaterial == null) skyboxMaterial = EditorManager.instance.basePrefabs.defaultSkyboxMaterial;
EditorManager.instance.backgroundController.SetSkybox(skyboxMaterial);
EditorManager.instance.backgroundController.EnableBackground(!useSkybox);
if (useSkybox)
{
SetSkybox(skyboxThemeBundleName, skyboxMaterialName);
}
else
{
SetBackgroundSprite(backgroundSpriteName);
}
}
}
public void SetBackgroundSprite(string backgroundSpriteName)
public partial class BackgroundSetter
{
public override void SaveBM()
{
string path = EditorManager.instance.projectInformation.projectPath + "/Sprites/" + backgroundSpriteName + ".png";
backgroundSprite = ES3.FileExists(path) ? ES3.Load<Sprite>(path) : EditorManager.instance.basePrefabs.defaultBackground;
EditorManager.instance.backgroundController.SetBackground(backgroundSprite);
}
public override void SetDefaultSubmodules()
{
matchedBM = new BackgroundSetter_BM(elementName, elementGuid, tags, null,
useSkybox, skyboxThemeBundleName, skyboxMaterialName, backgroundSpriteName);
}
public override void SetUpInspector()
@@ -73,34 +80,61 @@ namespace Ichni.Editor
useSkyboxToggle.AddListenerFunction(() => EditorManager.instance.backgroundController.EnableBackground(!useSkybox));
useSkyboxToggle.AddListenerFunction(() => SetInputFields(useSkybox));
}
}
public override void Refresh()
public partial class BackgroundSetter
{
private void SetSkybox(string themeBundleName, string materialName)
{
skyboxThemeBundleName = themeBundleName;
skyboxMaterialName = materialName;
skyboxMaterial = ThemeBundleManager.instance.GetObject<Material>(themeBundleName, materialName);
if (skyboxMaterial == null) skyboxMaterial = EditorManager.instance.basePrefabs.defaultSkyboxMaterial;
EditorManager.instance.backgroundController.SetSkybox(skyboxMaterial);
}
EditorManager.instance.backgroundController.EnableBackground(!useSkybox);
if (useSkybox)
{
SetSkybox(skyboxThemeBundleName, skyboxMaterialName);
}
else
{
SetBackgroundSprite(backgroundSpriteName);
}
private void SetBackgroundSprite(string spriteName)
{
string path = EditorManager.instance.projectInformation.projectPath + "/Sprites/" + spriteName + ".png";
backgroundSprite = ES3.FileExists(path) ? ES3.Load<Sprite>(path) : EditorManager.instance.basePrefabs.defaultBackground;
EditorManager.instance.backgroundController.SetBackground(backgroundSprite);
}
}
namespace Beatmap
{
public class BackgroundSetter_BM : BaseElement_BM
public class BackgroundSetter_BM : GameElement_BM
{
public bool useSkybox;
public string skyboxThemeBundleName;
public string skyboxMaterialName;
public string backgroundSpriteName;
public BackgroundSetter_BM()
{
}
public BackgroundSetter_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM attachedElement,
bool useSkybox, string skyboxThemeBundleName, string skyboxMaterialName, string backgroundSpriteName)
: base(elementName, elementGuid, tags, attachedElement)
{
this.useSkybox = useSkybox;
this.skyboxThemeBundleName = skyboxThemeBundleName;
this.skyboxMaterialName = skyboxMaterialName;
this.backgroundSpriteName = backgroundSpriteName;
}
public override void ExecuteBM()
{
throw new System.NotImplementedException();
matchedElement = BackgroundSetter.GenerateElement(elementName, elementGuid, tags, false,
GetElement(attachedElementGuid), useSkybox, skyboxThemeBundleName, skyboxMaterialName, backgroundSpriteName);
}
public override GameElement DuplicateBM(GameElement attached)
{
return BackgroundSetter.GenerateElement(elementName, Guid.NewGuid(), tags, false, attached,
useSkybox, skyboxThemeBundleName, skyboxMaterialName, backgroundSpriteName);
}
}
}

View File

@@ -0,0 +1,111 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using Unity.VisualScripting;
using UnityEngine;
namespace Ichni.RhythmGame
{
public partial class VariablesContainer : GameElement
{
public Dictionary<string, int> originalVariables;
public Dictionary<string, int> currentVariables;
public static VariablesContainer GenerateElement(string elementName, Guid id, List<string> tags, bool isFirstGenerated,
GameElement parentElement, Dictionary<string, int> variables)
{
if (EditorManager.instance.variablesContainer != null)
{
LogWindow.Log("There is already a Variables Container in the scene.", Color.red);
return null;
}
VariablesContainer variablesContainer =
Instantiate(EditorManager.instance.basePrefabs.emptyObject).AddComponent<VariablesContainer>();
EditorManager.instance.variablesContainer = variablesContainer;
variablesContainer.Initialize(elementName, id, tags, isFirstGenerated, parentElement);
variablesContainer.originalVariables = new Dictionary<string, int>(variables);
variablesContainer.currentVariables = new Dictionary<string, int>(variables);
return variablesContainer;
}
public void SetVariable(string variableName, int value)
{
currentVariables[variableName] = value;
}
public int GetVariable(string variableName)
{
return currentVariables[variableName];
}
public void RevertVariable(string variableName)
{
currentVariables[variableName] = originalVariables[variableName];
}
public void RevertAllVariables()
{
currentVariables = new Dictionary<string, int>(originalVariables);
}
}
public partial class VariablesContainer
{
public override void SaveBM()
{
matchedBM = new VariablesContainer_BM(elementName, elementGuid, tags, null, originalVariables);
}
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Variables Container");
var originalVariablesButton = inspector.GenerateButton(this, container, "Original Variables", () =>
{
var ov = inspector.GenerateCompositeParameterWindow(this, "Original Variables List", nameof(originalVariables));
ov.SetAsStringIntDictionary();
ov.AddListenerFunction(RevertAllVariables);
});
var currentVariablesButton = inspector.GenerateButton(this, container, "Current Variables", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Current Variables List", nameof(currentVariables)).SetAsStringIntDictionary();
});
}
}
namespace Beatmap
{
public class VariablesContainer_BM : GameElement_BM
{
public Dictionary<string, int> originalVariables;
public VariablesContainer_BM()
{
}
public VariablesContainer_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM parentElement,
Dictionary<string, int> originalVariables) : base(elementName, elementGuid, tags, parentElement)
{
this.originalVariables = new Dictionary<string, int>(originalVariables);
}
public override void ExecuteBM()
{
matchedElement = VariablesContainer.GenerateElement(elementName, elementGuid, tags, false,
GetElement(attachedElementGuid), originalVariables);
}
public override GameElement DuplicateBM(GameElement attached)
{
return VariablesContainer.GenerateElement(elementName, Guid.NewGuid(), tags, false, attached, originalVariables);
}
}
}
}

View File

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

View File

@@ -118,6 +118,8 @@ namespace Ichni.RhythmGame
noteVisual.effectSubmodule.effectCollection["Miss"].ForEach(e => e.UpdateEffect(exactJudgeTime));
break;
}
noteVisual.effectSubmodule.effectCollection["AfterJudge"].ForEach(e => e.UpdateEffect(exactJudgeTime));
if (EditorManager.instance.cameraManager.haveGameCamera)
{