QuickCopy & fix NoteEffects

This commit is contained in:
SoulliesOfficial
2025-02-21 14:08:32 -05:00
parent 70eddeb881
commit 187b2efdad
28 changed files with 277 additions and 60 deletions

View File

@@ -8,7 +8,7 @@ using UnityEngine.Serialization;
namespace Ichni.RhythmGame
{
public abstract class AnimationBase : GameElement, IHaveTimeDurationSubmodule
public abstract partial class AnimationBase : GameElement, IHaveTimeDurationSubmodule
{
public GameElement animatedObject;
public FlexibleReturnType animationReturnType;
@@ -21,6 +21,10 @@ namespace Ichni.RhythmGame
submoduleList.Add(timeDurationSubmodule);
}
/// <summary>
/// 更新动画
/// </summary>
/// <param name="songTime">歌曲时间</param>
protected abstract void UpdateAnimation(float songTime);
protected virtual void Update()
@@ -30,6 +34,16 @@ namespace Ichni.RhythmGame
UpdateAnimation(EditorManager.instance.songInformation.songTime);
}
}
/// <summary>
/// 施加时间偏移即移动所有Flexible参数的时间
/// </summary>
/// <param name="offset"></param>
public virtual void ApplyTimeOffset(float offset)
{
timeDurationSubmodule.startTime += offset;
timeDurationSubmodule.endTime += offset;
}
}
namespace Beatmap

View File

@@ -63,6 +63,15 @@ namespace Ichni.RhythmGame
animationReturnType = FlexibleReturnType.MiddleInterval;
}
}
public override void ApplyTimeOffset(float offset)
{
base.ApplyTimeOffset(offset);
colorR.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
colorG.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
colorB.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
colorA.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
}
}
public partial class BaseColorChange

View File

@@ -66,6 +66,15 @@ namespace Ichni.RhythmGame
animationReturnType = FlexibleReturnType.MiddleInterval;
}
}
public override void ApplyTimeOffset(float offset)
{
base.ApplyTimeOffset(offset);
colorR.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
colorG.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
colorB.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
colorI.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
}
}
public partial class EmissionColorChange

View File

@@ -45,6 +45,12 @@ namespace Ichni.RhythmGame
targetTrackTimeSubmoduleStatic.trackTotalTime = totalTime.value;
}
}
public override void ApplyTimeOffset(float offset)
{
base.ApplyTimeOffset(offset);
totalTime.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
}
}
public partial class TrackTotalTimeChange

View File

@@ -59,6 +59,14 @@ namespace Ichni.RhythmGame
animationReturnType = FlexibleReturnType.MiddleInterval;
}
}
public override void ApplyTimeOffset(float offset)
{
base.ApplyTimeOffset(offset);
positionX.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
positionY.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
positionZ.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
}
}
public partial class Displacement

View File

@@ -71,6 +71,12 @@ namespace Ichni.RhythmGame
matchedBM = new LookAt_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM,
enabling.ConvertToBM(), lookAtObject.elementGuid);
}
public override void ApplyTimeOffset(float offset)
{
base.ApplyTimeOffset(offset);
enabling.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
}
}
namespace Beatmap

View File

@@ -59,6 +59,14 @@ namespace Ichni.RhythmGame
animationReturnType = FlexibleReturnType.MiddleInterval;
}
}
public override void ApplyTimeOffset(float offset)
{
base.ApplyTimeOffset(offset);
scaleX.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
scaleY.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
scaleZ.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
}
}
public partial class Scale

View File

@@ -61,6 +61,14 @@ namespace Ichni.RhythmGame
animationReturnType = FlexibleReturnType.MiddleInterval;
}
}
public override void ApplyTimeOffset(float offset)
{
base.ApplyTimeOffset(offset);
eulerAngleX.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
eulerAngleY.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
eulerAngleZ.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
}
}
public partial class Swirl

View File

@@ -15,6 +15,11 @@ namespace Ichni.RhythmGame
this.value = value;
this.time = time;
}
public void ApplyTimeOffset(float offset)
{
time += offset;
}
}
[System.Serializable]

View File

@@ -26,6 +26,12 @@ namespace Ichni.RhythmGame
this.endTime = endTime;
this.animationCurveType = animationCurveType;
}
public void ApplyTimeOffset(float offset)
{
startTime += offset;
endTime += offset;
}
/// <summary>
/// 按照起始时间排序

View File

@@ -21,6 +21,11 @@ namespace Ichni.RhythmGame
this.value = value;
this.time = time;
}
public void ApplyTimeOffset(float offset)
{
time += offset;
}
}
[System.Serializable]

View File

@@ -2,7 +2,7 @@ using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Ichni
namespace Ichni.RhythmGame
{
public enum FlexibleReturnType
{

View File

@@ -45,7 +45,8 @@ namespace Ichni.RhythmGame
List<EffectBase> effectList = new List<EffectBase>();
foreach (var effectBM in effect.Value)
{
effectList.Add(effectBM.ConvertToGameType());
Debug.Log(attachedGameElement.GetType().ToString());
effectList.Add(effectBM.ConvertToGameType(attachedGameElement));
}
effectCollection.Add(effect.Key, effectList);
}
@@ -283,7 +284,7 @@ namespace Ichni.RhythmGame
/// 转换为游戏类
/// </summary>
/// <returns></returns>
public abstract EffectBase ConvertToGameType();
public abstract EffectBase ConvertToGameType(GameElement attachedGameElement);
}
}
}

View File

@@ -161,6 +161,26 @@ namespace Ichni.RhythmGame
submodule.SetUpInspector();
}
}
/// <summary>
/// 获取自身和所有子GameElement
/// </summary>
public List<GameElement> GetAllGameElementsFromThis()
{
void GetAllChildrenRecursively(GameElement parent, List<GameElement> elements)
{
foreach (var child in parent.childElementList)
{
elements.Add(child);
GetAllChildrenRecursively(child, elements);
}
}
List<GameElement> gameElements = new List<GameElement> { this };
GetAllChildrenRecursively(this, gameElements);
return gameElements;
}
}
namespace Beatmap

View File

@@ -64,7 +64,7 @@ namespace Ichni.RhythmGame
this.bloomPeak = bloomPeak;
}
public override EffectBase ConvertToGameType()
public override EffectBase ConvertToGameType(GameElement attachedGameElement)
{
return new BloomShake(bloomTime, bloomPeak);
}

View File

@@ -152,18 +152,16 @@ namespace Ichni.RhythmGame
var xField = qcWindow.GenerateGetterInputField(qcContainer, "X offset", "0");
var yField = qcWindow.GenerateGetterInputField(qcContainer, "Y offset", "0");
var zField = qcWindow.GenerateGetterInputField(qcContainer, "Z offset", "0");
var timeField = qcWindow.GenerateGetterInputField(qcContainer, "Time offset", "0");
var iterationField = qcWindow.GenerateGetterInputField(qcContainer, "Iteration", "0");
var includeAnimationToggle = qcWindow.GenerateToggle(null, qcContainer, "Include Animation", string.Empty);
qcWindow.GenerateButton(this, qcContainer, "Copy", () =>
{
CopyPasteDeleteModule cpd = EditorManager.instance.operationManager.CopyPasteDeleteModule;
cpd.CopyElement(this);
cpd.PasteElement(parentElement);
Track newTrack = cpd.pastedElementList[0] as Track;
newTrack.trackPathSubmodule.pathNodeList.ForEach(pn =>
{
Vector3 offset = new Vector3(xField.GetResult<float>(), yField.GetResult<float>(), zField.GetResult<float>());
pn.transformSubmodule.originalPosition += offset;
pn.transformSubmodule.Refresh();
});
Vector3 positionOffset = new Vector3(xField.GetResult<float>(), yField.GetResult<float>(), zField.GetResult<float>());
float timeOffset = timeField.GetResult<float>();
int iteration = iterationField.GetResult<int>();
bool includeAnimation = includeAnimationToggle.toggle.isOn;
QuickCopy(positionOffset, timeOffset, includeAnimation, iteration);
});
});

View File

@@ -0,0 +1,76 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Ichni.Editor;
using UnityEngine;
namespace Ichni.RhythmGame
{
public partial class Track
{
/// <summary>
/// 快速复制粘贴Track
/// </summary>
/// <param name="unitPositionOffset">单位位置整体偏移</param>
/// <param name="unitTimeOffset">单位时间偏移</param>
/// <param name="iteration">迭代次数即产生几个粘贴的Track</param>
private void QuickCopy(Vector3 unitPositionOffset, float unitTimeOffset, bool includeAnimations = true, int iteration = 1)
{
if(iteration <= 0) return;
CopyPasteDeleteModule cpd = EditorManager.instance.operationManager.CopyPasteDeleteModule;
cpd.CopyElement(this);
for (int i = 1; i <= iteration; i++)
{
cpd.PasteElement(parentElement);
Track newTrack = cpd.pastedElementList[0] as Track;
Vector3 positionOffset = unitPositionOffset * i;
float timeOffset = unitTimeOffset * i;
//对Track的所有有效的Submodule和子GameElement进行偏移
if (newTrack.trackTimeSubmodule is TrackTimeSubmoduleMovable movable)
{
movable.trackStartTime += timeOffset;
movable.trackEndTime += timeOffset;
}
newTrack.trackPathSubmodule.pathNodeList.ForEach(pn =>
{
pn.transformSubmodule.originalPosition += positionOffset;
pn.transformSubmodule.Refresh();
});
List<GameElement> allNewGameElements = newTrack.GetAllGameElementsFromThis();
List<TrackPercentPoint> percentPoints = allNewGameElements
.FindAll(x => x is TrackPercentPoint).Cast<TrackPercentPoint>().ToList();
percentPoints.ForEach(pp =>
{
pp.trackPercent.animations.ForEach(anim => anim.ApplyTimeOffset(timeOffset));
});
List<NoteBase> notes = allNewGameElements.FindAll(x => x is NoteBase).Cast<NoteBase>().ToList();
notes.ForEach(note =>
{
note.exactJudgeTime += timeOffset;
note.Refresh();
});
if (includeAnimations)
{
List<AnimationBase> animations = allNewGameElements
.FindAll(x => x.GetType().IsSubclassOf(typeof(AnimationBase))).Cast<AnimationBase>().ToList();
animations.ForEach(anim =>
{
anim.ApplyTimeOffset(timeOffset);
});
}
}
cpd.pastedElementList.Clear();
}
}
}

View File

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