效果模块,以及代码位置整理
This commit is contained in:
BIN
Assets/Scripts/EditorGame/Base/.DS_Store
vendored
Normal file
BIN
Assets/Scripts/EditorGame/Base/.DS_Store
vendored
Normal file
Binary file not shown.
71
Assets/Scripts/EditorGame/Base/BaseElement.cs
Normal file
71
Assets/Scripts/EditorGame/Base/BaseElement.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ichni.Editor;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using Sirenix.OdinInspector;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public interface IBaseElement
|
||||
{
|
||||
public BaseElement_BM matchedBM { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用于生成存档
|
||||
/// </summary>
|
||||
public void SaveBM();
|
||||
|
||||
/// <summary>
|
||||
/// 刷新物体的状态
|
||||
/// </summary>
|
||||
public void Refresh();
|
||||
|
||||
/// <summary>
|
||||
/// 当物体被删除时执行的方法
|
||||
/// </summary>
|
||||
public void OnDelete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除物体,包括所有子物体
|
||||
/// </summary>
|
||||
public void Delete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Inspector inspector => EditorManager.instance.uiManager.inspector;
|
||||
public void SetUpInspector();
|
||||
}
|
||||
|
||||
// public virtual void SetTimeDuration()
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public void ApplyTimeDuration()
|
||||
// {
|
||||
// childElementList.ForEach(x => x.ApplyTimeDuration());
|
||||
// timeDurationSubmodule?.SetDurationFromChildren(
|
||||
// childElementList.Select(x => x.timeDurationSubmodule).ToList());
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public abstract class BaseElement_BM
|
||||
{
|
||||
/// <summary>
|
||||
/// 从存档类中生成游戏物体
|
||||
/// </summary>
|
||||
public abstract void ExecuteBM();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/EditorGame/Base/BaseElement.cs.meta
Normal file
11
Assets/Scripts/EditorGame/Base/BaseElement.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3baa26d781a184a3e804d78965a79336
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/EditorGame/Base/EaseCurve.meta
Normal file
8
Assets/Scripts/EditorGame/Base/EaseCurve.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fda5a36c77610481e976e5d7ceb764ab
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
397
Assets/Scripts/EditorGame/Base/EaseCurve/EaseCurve.cs
Normal file
397
Assets/Scripts/EditorGame/Base/EaseCurve/EaseCurve.cs
Normal file
@@ -0,0 +1,397 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ichni
|
||||
{
|
||||
public enum AnimationCurveType //预设动画曲线类型
|
||||
{
|
||||
Linear = 0,
|
||||
InQuad = 1,
|
||||
OutQuad = 2,
|
||||
InOutQuad = 3,
|
||||
InCubic = 4,
|
||||
OutCubic = 5,
|
||||
InOutCubic = 6,
|
||||
InQuart = 7,
|
||||
OutQuart = 8,
|
||||
InOutQuart = 9,
|
||||
InQuint = 10,
|
||||
OutQuint = 11,
|
||||
InOutQuint = 12,
|
||||
InSine = 13,
|
||||
OutSine = 14,
|
||||
InOutSine = 15,
|
||||
InExpo = 16,
|
||||
OutExpo = 17,
|
||||
InOutExpo = 18,
|
||||
InCirc = 19,
|
||||
OutCirc = 20,
|
||||
InOutCirc = 21,
|
||||
InBounce = 22,
|
||||
OutBounce = 23,
|
||||
InOutBounce = 24,
|
||||
InElastic = 25,
|
||||
OutElastic = 26,
|
||||
InOutElastic = 27,
|
||||
InBack = 28,
|
||||
OutBack = 29,
|
||||
InOutBack = 30
|
||||
}
|
||||
|
||||
public static class AnimationCurveEvaluator
|
||||
{
|
||||
public static float Evaluate(AnimationCurveType animationCurveType, float t)
|
||||
{
|
||||
t = Mathf.Clamp(t, 0, 1);
|
||||
|
||||
switch (animationCurveType)
|
||||
{
|
||||
case AnimationCurveType.Linear:
|
||||
return Linear(0, 1, t);
|
||||
case AnimationCurveType.InQuad:
|
||||
return InQuad(0, 1, t);
|
||||
case AnimationCurveType.OutQuad:
|
||||
return OutQuad(0, 1, t);
|
||||
case AnimationCurveType.InOutQuad:
|
||||
return InOutQuad(0, 1, t);
|
||||
case AnimationCurveType.InCubic:
|
||||
return InCubic(0, 1, t);
|
||||
case AnimationCurveType.OutCubic:
|
||||
return OutCubic(0, 1, t);
|
||||
case AnimationCurveType.InOutCubic:
|
||||
return InOutCubic(0, 1, t);
|
||||
case AnimationCurveType.InQuart:
|
||||
return InQuart(0, 1, t);
|
||||
case AnimationCurveType.OutQuart:
|
||||
return OutQuart(0, 1, t);
|
||||
case AnimationCurveType.InOutQuart:
|
||||
return InOutQuart(0, 1, t);
|
||||
case AnimationCurveType.InQuint:
|
||||
return InQuint(0, 1, t);
|
||||
case AnimationCurveType.OutQuint:
|
||||
return OutQuint(0, 1, t);
|
||||
case AnimationCurveType.InOutQuint:
|
||||
return InOutQuint(0, 1, t);
|
||||
case AnimationCurveType.InSine:
|
||||
return InSine(0, 1, t);
|
||||
case AnimationCurveType.OutSine:
|
||||
return OutSine(0, 1, t);
|
||||
case AnimationCurveType.InOutSine:
|
||||
return InOutSine(0, 1, t);
|
||||
case AnimationCurveType.InExpo:
|
||||
return InExpo(0, 1, t);
|
||||
case AnimationCurveType.OutExpo:
|
||||
return OutExpo(0, 1, t);
|
||||
case AnimationCurveType.InOutExpo:
|
||||
return InOutExpo(0, 1, t);
|
||||
case AnimationCurveType.InCirc:
|
||||
return InCirc(0, 1, t);
|
||||
case AnimationCurveType.OutCirc:
|
||||
return OutCirc(0, 1, t);
|
||||
case AnimationCurveType.InOutCirc:
|
||||
return InOutCirc(0, 1, t);
|
||||
case AnimationCurveType.InBounce:
|
||||
return InBounce(0, 1, t);
|
||||
case AnimationCurveType.OutBounce:
|
||||
return OutBounce(0, 1, t);
|
||||
case AnimationCurveType.InOutBounce:
|
||||
return InOutBounce(0, 1, t);
|
||||
case AnimationCurveType.InElastic:
|
||||
return InElastic(0, 1, t);
|
||||
case AnimationCurveType.OutElastic:
|
||||
return OutElastic(0, 1, t);
|
||||
case AnimationCurveType.InOutElastic:
|
||||
return InOutElastic(0, 1, t);
|
||||
case AnimationCurveType.InBack:
|
||||
return InBack(0, 1, t);
|
||||
case AnimationCurveType.OutBack:
|
||||
return OutBack(0, 1, t);
|
||||
case AnimationCurveType.InOutBack:
|
||||
return InOutBack(0, 1, t);
|
||||
}
|
||||
|
||||
throw new NotImplementedException($"Animation curve type {animationCurveType} is not implemented.");
|
||||
}
|
||||
|
||||
#region 缓动曲线计算式
|
||||
private static float Linear(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 1f;
|
||||
return c * t / 1f + from;
|
||||
}
|
||||
|
||||
private static float InQuad(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 1f;
|
||||
return c * t * t + from;
|
||||
}
|
||||
|
||||
private static float OutQuad(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 1f;
|
||||
return -c * t * (t - 2f) + from;
|
||||
}
|
||||
|
||||
private static float InOutQuad(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 0.5f;
|
||||
if (t < 1) return c / 2f * t * t + from;
|
||||
t--;
|
||||
return -c / 2f * (t * (t - 2) - 1) + from;
|
||||
}
|
||||
|
||||
private static float InCubic(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 1f;
|
||||
return c * t * t * t + from;
|
||||
}
|
||||
|
||||
private static float OutCubic(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 1f;
|
||||
t--;
|
||||
return c * (t * t * t + 1) + from;
|
||||
}
|
||||
|
||||
private static float InOutCubic(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 0.5f;
|
||||
if (t < 1) return c / 2f * t * t * t + from;
|
||||
t -= 2;
|
||||
return c / 2f * (t * t * t + 2) + from;
|
||||
}
|
||||
|
||||
private static float InQuart(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 1f;
|
||||
return c * t * t * t * t + from;
|
||||
}
|
||||
|
||||
private static float OutQuart(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 1f;
|
||||
t--;
|
||||
return -c * (t * t * t * t - 1) + from;
|
||||
}
|
||||
|
||||
private static float InOutQuart(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 0.5f;
|
||||
if (t < 1) return c / 2f * t * t * t * t + from;
|
||||
t -= 2;
|
||||
return -c / 2f * (t * t * t * t - 2) + from;
|
||||
}
|
||||
|
||||
private static float InQuint(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 1f;
|
||||
return c * t * t * t * t * t + from;
|
||||
}
|
||||
|
||||
private static float OutQuint(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 1f;
|
||||
t--;
|
||||
return c * (t * t * t * t * t + 1) + from;
|
||||
}
|
||||
|
||||
private static float InOutQuint(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 0.5f;
|
||||
if (t < 1) return c / 2f * t * t * t * t * t + from;
|
||||
t -= 2;
|
||||
return c / 2f * (t * t * t * t * t + 2) + from;
|
||||
}
|
||||
|
||||
private static float InSine(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
return -c * Mathf.Cos(t / 1f * (Mathf.PI / 2f)) + c + from;
|
||||
}
|
||||
|
||||
private static float OutSine(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
return c * Mathf.Sin(t / 1f * (Mathf.PI / 2f)) + from;
|
||||
}
|
||||
|
||||
private static float InOutSine(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
return -c / 2f * (Mathf.Cos(Mathf.PI * t / 1f) - 1) + from;
|
||||
}
|
||||
|
||||
private static float InExpo(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
return c * Mathf.Pow(2, 10 * (t / 1f - 1)) + from;
|
||||
}
|
||||
|
||||
private static float OutExpo(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
return c * (-Mathf.Pow(2, -10 * t / 1f) + 1) + from;
|
||||
}
|
||||
|
||||
private static float InOutExpo(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 0.5f;
|
||||
if (t < 1f) return c / 2f * Mathf.Pow(2, 10 * (t - 1)) + from;
|
||||
t--;
|
||||
return c / 2f * (-Mathf.Pow(2, -10 * t) + 2) + from;
|
||||
}
|
||||
|
||||
private static float InCirc(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 1f;
|
||||
return -c * (Mathf.Sqrt(1 - t * t) - 1) + from;
|
||||
}
|
||||
|
||||
private static float OutCirc(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 1f;
|
||||
t--;
|
||||
return c * Mathf.Sqrt(1 - t * t) + from;
|
||||
}
|
||||
|
||||
private static float InOutCirc(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
t /= 0.5f;
|
||||
if (t < 1) return -c / 2f * (Mathf.Sqrt(1 - t * t) - 1) + from;
|
||||
t -= 2;
|
||||
return c / 2f * (Mathf.Sqrt(1 - t * t) + 1) + from;
|
||||
}
|
||||
|
||||
private static float InBounce(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
return c - OutBounce(0f, c, 1f - t) + from; //does this work?
|
||||
}
|
||||
|
||||
private static float OutBounce(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
|
||||
if ((t /= 1f) < (1 / 2.75f))
|
||||
{
|
||||
return c * (7.5625f * t * t) + from;
|
||||
}
|
||||
else if (t < (2 / 2.75f))
|
||||
{
|
||||
return c * (7.5625f * (t -= (1.5f / 2.75f)) * t + .75f) + from;
|
||||
}
|
||||
else if (t < (2.5 / 2.75))
|
||||
{
|
||||
return c * (7.5625f * (t -= (2.25f / 2.75f)) * t + .9375f) + from;
|
||||
}
|
||||
else
|
||||
{
|
||||
return c * (7.5625f * (t -= (2.625f / 2.75f)) * t + .984375f) + from;
|
||||
}
|
||||
}
|
||||
|
||||
private static float InOutBounce(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
if (t < 0.5f) return InBounce(0, c, t * 2f) * 0.5f + from;
|
||||
return OutBounce(0, c, t * 2 - 1) * 0.5f + c * 0.5f + from;
|
||||
|
||||
}
|
||||
|
||||
private static float InElastic(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
if (t == 0) return from;
|
||||
if ((t /= 1f) == 1) return from + c;
|
||||
float p = 0.3f;
|
||||
float s = p / 4f;
|
||||
return -(c * Mathf.Pow(2, 10 * (t -= 1)) * Mathf.Sin((t - s) * (2 * Mathf.PI) / p)) + from;
|
||||
}
|
||||
|
||||
private static float OutElastic(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
if (t == 0) return from;
|
||||
if ((t /= 1f) == 1) return from + c;
|
||||
float p = 0.3f;
|
||||
float s = p / 4f;
|
||||
return (c * Mathf.Pow(2, -10 * t) * Mathf.Sin((t - s) * (2 * Mathf.PI) / p) + c + from);
|
||||
}
|
||||
|
||||
private static float InOutElastic(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
if (t == 0) return from;
|
||||
if ((t /= 0.5f) == 2) return from + c;
|
||||
float p = 0.3f * 1.5f;
|
||||
float s = p / 4f;
|
||||
if (t < 1)
|
||||
return -0.5f * (c * Mathf.Pow(2, 10 * (t -= 1f)) * Mathf.Sin((t - 2) * (2 * Mathf.PI) / p)) + from;
|
||||
return c * Mathf.Pow(2, -10 * (t -= 1)) * Mathf.Sin((t - s) * (2f * Mathf.PI) / p) * 0.5f + c + from;
|
||||
}
|
||||
|
||||
private static float InBack(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
float s = 1.70158f;
|
||||
t /= 0.5f;
|
||||
return c * t * t * ((s + 1) * t - s) + from;
|
||||
}
|
||||
|
||||
private static float OutBack(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
float s = 1.70158f;
|
||||
t = t / 1f - 1f;
|
||||
return c * (t * t * ((s + 1) * t + s) + 1) + from;
|
||||
}
|
||||
|
||||
private static float InOutBack(float from, float to, float t)
|
||||
{
|
||||
float c = to - from;
|
||||
float s = 1.70158f;
|
||||
t /= 0.5f;
|
||||
if (t < 1) return c / 2f * (t * t * (((s *= (1.525f)) + 1) * t - s)) + from;
|
||||
t -= 2;
|
||||
return c / 2f * (t * t * (((s *= (1.525f)) + 1) * t + s) + 2) + from;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
// [System.Serializable]
|
||||
// public class PresetAnimationCurve
|
||||
// {
|
||||
// public AnimationCurveType animationCurveType; //动画曲线类型
|
||||
//
|
||||
// public PresetAnimationCurve(AnimationCurveType animationCurveType)
|
||||
// {
|
||||
// this.animationCurveType = animationCurveType;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 根据Type选择曲线,并计算t点(0,1)时曲线的值,若t越界,则直接返回0或1
|
||||
// /// </summary>
|
||||
// public float Evaluate(float t)
|
||||
// {
|
||||
// return AnimationCurveEvaluator.Evaluate(this.animationCurveType, t);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
11
Assets/Scripts/EditorGame/Base/EaseCurve/EaseCurve.cs.meta
Normal file
11
Assets/Scripts/EditorGame/Base/EaseCurve/EaseCurve.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ad11ce603af64e4fb032229b82386b7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/EditorGame/Base/FlexibleTypes.meta
Normal file
8
Assets/Scripts/EditorGame/Base/FlexibleTypes.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6924511d06874727a50bcbd03bc326a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
126
Assets/Scripts/EditorGame/Base/FlexibleTypes/FlexibleBool.cs
Normal file
126
Assets/Scripts/EditorGame/Base/FlexibleTypes/FlexibleBool.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
[System.Serializable]
|
||||
public class AnimatedBool
|
||||
{
|
||||
public bool value; //bool值
|
||||
public float time; //当前时间
|
||||
|
||||
public AnimatedBool(float time, bool value)
|
||||
{
|
||||
this.value = value;
|
||||
this.time = time;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class FlexibleBool
|
||||
{
|
||||
public bool value;
|
||||
public List<AnimatedBool> animations;
|
||||
|
||||
public FlexibleBool()
|
||||
{
|
||||
animations = new List<AnimatedBool>();
|
||||
}
|
||||
|
||||
public FlexibleBool(List<AnimatedBool> anim)
|
||||
{
|
||||
this.animations = anim;
|
||||
}
|
||||
|
||||
public void Add(AnimatedBool animatedBool)
|
||||
{
|
||||
animations.Add(animatedBool);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在动画脚本的Update中更新Bool Value
|
||||
/// </summary>
|
||||
/// <param name="歌曲时间"></param>
|
||||
public FlexibleReturnType UpdateFlexibleBool(float nowTime)
|
||||
{
|
||||
AnimatedBool nowAnimatedBool = GetAnimatedBool(nowTime); //获取当前时间点对应的AnimatedBool
|
||||
value = nowAnimatedBool.value; //更新value
|
||||
return FlexibleReturnType.MiddleExecuting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取songTime对应的AnimatedBool的时间段
|
||||
/// </summary>
|
||||
/// <param name="歌曲时间"></param>
|
||||
/// <returns>返回距离当前时间最近的前一个AnimatedBool</returns>
|
||||
AnimatedBool GetAnimatedBool(float nowTime)
|
||||
{
|
||||
for (int i = 0; i < animations.Count; i++)
|
||||
{
|
||||
if (nowTime >= animations[i].time)
|
||||
{
|
||||
return animations[i];
|
||||
}
|
||||
}
|
||||
|
||||
return new AnimatedBool(0, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为Beatmap存档类型
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public FlexibleBool_BM ConvertToBM()
|
||||
{
|
||||
FlexibleBool_BM flexibleBool_BM = new FlexibleBool_BM();
|
||||
|
||||
foreach (AnimatedBool animatedBool in animations)
|
||||
{
|
||||
flexibleBool_BM.animatedBoolList.Add(new AnimatedBool(animatedBool.time, animatedBool.value));
|
||||
}
|
||||
|
||||
return flexibleBool_BM;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public class FlexibleBool_BM
|
||||
{
|
||||
public List<AnimatedBool> animatedBoolList;
|
||||
|
||||
public FlexibleBool_BM()
|
||||
{
|
||||
this.animatedBoolList = new List<AnimatedBool>();
|
||||
}
|
||||
|
||||
public FlexibleBool_BM(List<AnimatedBool> animatedBoolList)
|
||||
{
|
||||
this.animatedBoolList = animatedBoolList;
|
||||
}
|
||||
|
||||
public FlexibleBool ConvertToGameType()
|
||||
{
|
||||
FlexibleBool flexibleBool;
|
||||
|
||||
if (this.animatedBoolList.Count == 0)
|
||||
{
|
||||
flexibleBool = new FlexibleBool();
|
||||
}
|
||||
else
|
||||
{
|
||||
List<AnimatedBool> animations = new List<AnimatedBool>();
|
||||
foreach (AnimatedBool animatedBool in animatedBoolList)
|
||||
{
|
||||
animations.Add(new AnimatedBool(animatedBool.time, animatedBool.value));
|
||||
}
|
||||
|
||||
flexibleBool = new FlexibleBool(animations);
|
||||
}
|
||||
|
||||
return flexibleBool;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43cce55e6aac440e9b664e917adc2f74
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
213
Assets/Scripts/EditorGame/Base/FlexibleTypes/FlexibleFloat.cs
Normal file
213
Assets/Scripts/EditorGame/Base/FlexibleTypes/FlexibleFloat.cs
Normal file
@@ -0,0 +1,213 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
[System.Serializable]
|
||||
public class AnimatedFloat : IComparable<AnimatedFloat>
|
||||
{
|
||||
public float startValue, endValue; //起止值
|
||||
public float startTime, endTime; //起止时间
|
||||
public AnimationCurveType animationCurveType; //动画曲线类型
|
||||
|
||||
public float differenceValue => endValue - startValue; //差值
|
||||
public float totalTime => endTime - startTime; //总时间
|
||||
|
||||
|
||||
public AnimatedFloat(float startTime, float endTime, float startValue, float endValue,
|
||||
AnimationCurveType animationCurveType)
|
||||
{
|
||||
this.startValue = startValue;
|
||||
this.endValue = endValue;
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
this.animationCurveType = animationCurveType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按照起始时间排序
|
||||
/// </summary>
|
||||
public int CompareTo(AnimatedFloat obj)
|
||||
{
|
||||
return startTime.CompareTo(obj.startTime);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class FlexibleFloat
|
||||
{
|
||||
public float value;
|
||||
public int currentAnimationIndex;
|
||||
public List<AnimatedFloat> animations;
|
||||
public FlexibleReturnType returnType;
|
||||
|
||||
public FlexibleFloat()
|
||||
{
|
||||
animations = new List<AnimatedFloat>();
|
||||
}
|
||||
|
||||
public FlexibleFloat(List<AnimatedFloat> anim)
|
||||
{
|
||||
animations = anim;
|
||||
}
|
||||
|
||||
public void Add(AnimatedFloat animatedFloat)
|
||||
{
|
||||
animations.Add(animatedFloat);
|
||||
}
|
||||
|
||||
public void Sort()
|
||||
{
|
||||
animations.Sort();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 在动画脚本的Update中更新value
|
||||
/// </summary>
|
||||
/// <param name="歌曲时间"></param>
|
||||
public void UpdateFlexibleFloat(float nowTime)
|
||||
{
|
||||
AnimatedFloat nowAnimatedFloat = GetAnimatedFloat(nowTime); //获取当前时间点对应的AnimatedFloat
|
||||
if (nowAnimatedFloat != null) //如果能获取到,表明当前时间点存在动画
|
||||
{
|
||||
//获取songTime时间点时,基于动画曲线的AnimatedFloat比例点->(0,1)。
|
||||
float nowPercent = AnimationCurveEvaluator.Evaluate(nowAnimatedFloat.animationCurveType,
|
||||
(nowTime - nowAnimatedFloat.startTime) / nowAnimatedFloat.totalTime);
|
||||
value = nowAnimatedFloat.startValue + nowPercent * nowAnimatedFloat.differenceValue; //计算value
|
||||
returnType = FlexibleReturnType.MiddleExecuting;
|
||||
return;
|
||||
}
|
||||
|
||||
if (animations.Count > 0) //如果当前时间点没有动画
|
||||
{
|
||||
float finalStartTime = animations[0].startTime;
|
||||
float finalEndTime = animations[animations.Count - 1].endTime;
|
||||
|
||||
if (nowTime < finalStartTime) //如果当前时间小于第一个动画的开始时间
|
||||
{
|
||||
nowAnimatedFloat = animations[0];
|
||||
//nowPercent = 0;
|
||||
|
||||
if (nowAnimatedFloat != null)
|
||||
{
|
||||
value = nowAnimatedFloat.startValue;
|
||||
}
|
||||
|
||||
returnType = FlexibleReturnType.Before;
|
||||
return;
|
||||
}
|
||||
|
||||
if (nowTime > finalEndTime) //如果当前时间大于最后一个动画的结束时间
|
||||
{
|
||||
nowAnimatedFloat = animations[animations.Count - 1];
|
||||
//nowPercent = 1;
|
||||
|
||||
if (nowAnimatedFloat != null)
|
||||
{
|
||||
value = nowAnimatedFloat.endValue;
|
||||
}
|
||||
|
||||
returnType = FlexibleReturnType.After;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentAnimationIndex >= 0) //如果当前时间点在动画之间
|
||||
{
|
||||
value = animations[currentAnimationIndex].endValue;
|
||||
}
|
||||
|
||||
returnType = FlexibleReturnType.MiddleInterval;
|
||||
return;
|
||||
}
|
||||
|
||||
//如果没有动画
|
||||
value = 0;
|
||||
returnType = FlexibleReturnType.None;
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取songTime对应的AnimatedFloat的时间段
|
||||
/// </summary>
|
||||
/// <param name="歌曲时间"></param>
|
||||
/// <returns></returns>
|
||||
AnimatedFloat GetAnimatedFloat(float nowTime)
|
||||
{
|
||||
for (int i = 0; i < animations.Count; i++)
|
||||
{
|
||||
if (nowTime >= animations[i].startTime && nowTime <= animations[i].endTime)
|
||||
{
|
||||
currentAnimationIndex = i;
|
||||
return animations[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 转换为Beatmap存档类型
|
||||
/// </summary>
|
||||
public FlexibleFloat_BM ConvertToBM()
|
||||
{
|
||||
FlexibleFloat_BM flexibleFloat_BM = new FlexibleFloat_BM();
|
||||
|
||||
foreach (AnimatedFloat animatedFloat in animations)
|
||||
{
|
||||
flexibleFloat_BM.animatedFloatList.Add(new AnimatedFloat(animatedFloat.startTime, animatedFloat.endTime,
|
||||
animatedFloat.startValue, animatedFloat.endValue, animatedFloat.animationCurveType));
|
||||
}
|
||||
|
||||
return flexibleFloat_BM;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
[System.Serializable]
|
||||
public class FlexibleFloat_BM
|
||||
{
|
||||
public List<AnimatedFloat> animatedFloatList;
|
||||
|
||||
public FlexibleFloat_BM()
|
||||
{
|
||||
this.animatedFloatList = new List<AnimatedFloat>();
|
||||
}
|
||||
|
||||
public FlexibleFloat_BM(List<AnimatedFloat> animatedFloatList)
|
||||
{
|
||||
this.animatedFloatList = animatedFloatList;
|
||||
}
|
||||
|
||||
public FlexibleFloat ConvertToGameType()
|
||||
{
|
||||
FlexibleFloat flexibleFloat;
|
||||
|
||||
if (animatedFloatList.Count == 0)
|
||||
{
|
||||
flexibleFloat = new FlexibleFloat();
|
||||
}
|
||||
else
|
||||
{
|
||||
List<AnimatedFloat> animatedFloatList = new List<AnimatedFloat>();
|
||||
foreach (AnimatedFloat animatedFloat in this.animatedFloatList)
|
||||
{
|
||||
animatedFloatList.Add(new AnimatedFloat(
|
||||
animatedFloat.startTime, animatedFloat.endTime,
|
||||
animatedFloat.startValue, animatedFloat.endValue,
|
||||
animatedFloat.animationCurveType));
|
||||
}
|
||||
|
||||
flexibleFloat = new FlexibleFloat(animatedFloatList);
|
||||
}
|
||||
|
||||
return flexibleFloat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42c83e2f698b543f98d2cfcfb1ac5228
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
141
Assets/Scripts/EditorGame/Base/FlexibleTypes/FlexibleInt.cs
Normal file
141
Assets/Scripts/EditorGame/Base/FlexibleTypes/FlexibleInt.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
[System.Serializable]
|
||||
public class AnimatedInt
|
||||
{
|
||||
public int value; //值
|
||||
public float time;
|
||||
|
||||
public AnimatedInt()
|
||||
{
|
||||
}
|
||||
|
||||
public AnimatedInt(float time, int value)
|
||||
{
|
||||
this.value = value;
|
||||
this.time = time;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class FlexibleInt
|
||||
{
|
||||
public int value;
|
||||
public List<AnimatedInt> animations;
|
||||
|
||||
public FlexibleInt()
|
||||
{
|
||||
animations = new List<AnimatedInt>();
|
||||
}
|
||||
|
||||
public FlexibleInt(List<AnimatedInt> anim)
|
||||
{
|
||||
this.animations = anim;
|
||||
}
|
||||
|
||||
public void Add(AnimatedInt animatedInt)
|
||||
{
|
||||
animations.Add(animatedInt);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在动画脚本的Update中更新Int Value
|
||||
/// </summary>
|
||||
/// <param name="歌曲时间"></param>
|
||||
public FlexibleReturnType UpdateFlexibleInt(float nowTime)
|
||||
{
|
||||
AnimatedInt nowAnimatedInt = GetAnimatedInt(nowTime); //获取当前时间点对应的AnimatedInt
|
||||
value = nowAnimatedInt.value; //更新value
|
||||
return FlexibleReturnType.MiddleExecuting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取songTime对应的AnimatedInt的时间段
|
||||
/// </summary>
|
||||
/// <param name="歌曲时间"></param>
|
||||
/// <returns>返回距离当前时间最近的前一个AnimatedInt</returns>
|
||||
AnimatedInt GetAnimatedInt(float nowTime)
|
||||
{
|
||||
for (int i = 0; i < animations.Count; i++)
|
||||
{
|
||||
if (nowTime < animations[i].time)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
return animations[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
return animations[i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new AnimatedInt(0, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为Beatmap存档类型
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public FlexibleInt_BM ConvertToBM()
|
||||
{
|
||||
FlexibleInt_BM flexibleInt_BM = new FlexibleInt_BM();
|
||||
|
||||
foreach (AnimatedInt animatedInt in animations)
|
||||
{
|
||||
flexibleInt_BM.animatedIntList.Add(new AnimatedInt(animatedInt.time, animatedInt.value));
|
||||
}
|
||||
|
||||
return flexibleInt_BM;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
[System.Serializable]
|
||||
public class FlexibleInt_BM
|
||||
{
|
||||
public List<AnimatedInt> animatedIntList;
|
||||
|
||||
public FlexibleInt_BM()
|
||||
{
|
||||
this.animatedIntList = new List<AnimatedInt>();
|
||||
}
|
||||
|
||||
public FlexibleInt_BM(List<AnimatedInt> animatedIntList)
|
||||
{
|
||||
this.animatedIntList = animatedIntList;
|
||||
}
|
||||
|
||||
public FlexibleInt ConvertToGameType()
|
||||
{
|
||||
FlexibleInt flexibleInt;
|
||||
|
||||
if (animatedIntList.Count == 0)
|
||||
{
|
||||
flexibleInt = new FlexibleInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
List<AnimatedInt> animations = new List<AnimatedInt>();
|
||||
|
||||
foreach (AnimatedInt animatedInt in animatedIntList)
|
||||
{
|
||||
animations.Add(new AnimatedInt(animatedInt.time, animatedInt.value));
|
||||
}
|
||||
|
||||
flexibleInt = new FlexibleInt(animations);
|
||||
}
|
||||
|
||||
return flexibleInt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 824c05113512f41048fc8189760bd7cc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
15
Assets/Scripts/EditorGame/Base/FlexibleTypes/FlexibleMain.cs
Normal file
15
Assets/Scripts/EditorGame/Base/FlexibleTypes/FlexibleMain.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni
|
||||
{
|
||||
public enum FlexibleReturnType
|
||||
{
|
||||
None = -1, //没动画
|
||||
Before = 0, //动画开始之前
|
||||
MiddleExecuting = 1, //动画中间,正在运动
|
||||
MiddleInterval = 2, //动画中间,在停顿空隙
|
||||
After = 3 //动画结束后
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cad422c05863e4450a72bebb82f264c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/EditorGame/Base/GeneralSubmodules.meta
Normal file
8
Assets/Scripts/EditorGame/Base/GeneralSubmodules.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f5c439efd47f46888026603e35d5a4e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,137 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
/// <summary>
|
||||
/// 含有颜色属性的次级模块,包括基础颜色(透明度)、发光颜色和发光强度
|
||||
/// </summary>
|
||||
public partial class ColorSubmodule : SubmoduleBase
|
||||
{
|
||||
public Color originalBaseColor;
|
||||
public bool emissionEnabled;
|
||||
public Color originalEmissionColor;
|
||||
public float originalEmissionIntensity;
|
||||
|
||||
public List<Color> baseColorOffset = new List<Color>();
|
||||
public List<Color> emissionColorOffset = new List<Color>();
|
||||
public List<float> emissionIntensityOffset = new List<float>();
|
||||
|
||||
public Color currentBaseColor;
|
||||
public Color currentEmissionColor;
|
||||
public float currentEmissionIntensity;
|
||||
|
||||
public bool baseColorDirtyMark;
|
||||
public bool emissionColorDirtyMark;
|
||||
|
||||
public ColorSubmodule(GameElement attachedGameElement) : base(attachedGameElement)
|
||||
{
|
||||
this.originalBaseColor = Color.white;
|
||||
this.emissionEnabled = false;
|
||||
this.originalEmissionColor = Color.black;
|
||||
this.originalEmissionIntensity = 0;
|
||||
|
||||
this.currentBaseColor = Color.white;
|
||||
this.currentEmissionColor = Color.black;
|
||||
this.currentEmissionIntensity = 0;
|
||||
|
||||
this.baseColorDirtyMark = false;
|
||||
this.emissionColorDirtyMark = false;
|
||||
}
|
||||
|
||||
public ColorSubmodule(GameElement attachedGameElement, Color originalBaseColor) : base(attachedGameElement)
|
||||
{
|
||||
this.originalBaseColor = originalBaseColor;
|
||||
this.emissionEnabled = false;
|
||||
this.originalEmissionColor = Color.black;
|
||||
this.originalEmissionIntensity = 0;
|
||||
|
||||
this.currentBaseColor = originalBaseColor;
|
||||
this.currentEmissionColor = Color.black;
|
||||
this.currentEmissionIntensity = 0;
|
||||
|
||||
this.baseColorDirtyMark = false;
|
||||
this.emissionColorDirtyMark = false;
|
||||
}
|
||||
|
||||
public ColorSubmodule(GameElement attachedGameElement, Color originalBaseColor, bool emissionEnabled,
|
||||
Color originalEmissionColor, float originalEmissionIntensity) : base(attachedGameElement)
|
||||
{
|
||||
this.originalBaseColor = originalBaseColor;
|
||||
this.emissionEnabled = emissionEnabled;
|
||||
this.originalEmissionColor = originalEmissionColor;
|
||||
this.originalEmissionIntensity = originalEmissionIntensity;
|
||||
|
||||
this.currentBaseColor = originalBaseColor;
|
||||
this.currentEmissionColor = originalEmissionColor;
|
||||
this.currentEmissionIntensity = originalEmissionIntensity;
|
||||
|
||||
this.baseColorDirtyMark = false;
|
||||
this.emissionColorDirtyMark = false;
|
||||
}
|
||||
|
||||
public override void SaveBM()
|
||||
{
|
||||
matchedBM = new ColorSubmodule_BM(attachedGameElement);
|
||||
}
|
||||
|
||||
public override void SetUpInspector()
|
||||
{
|
||||
var container = inspector.GenerateContainer("Color");
|
||||
var baseColor = inspector.GenerateBaseColorPicker(this, container, "Base Color", nameof(originalBaseColor));
|
||||
if ((attachedGameElement as IHaveColorSubmodule).haveEmission)
|
||||
{
|
||||
var emissionColor = inspector.GenerateEmissionColorPicker(this, container, "Emission Color",
|
||||
nameof(emissionEnabled), nameof(originalEmissionColor), nameof(originalEmissionIntensity));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface IHaveColorSubmodule
|
||||
{
|
||||
public ColorSubmodule colorSubmodule { get; set; }
|
||||
public bool haveEmission { get; }
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public class ColorSubmodule_BM : Submodule_BM
|
||||
{
|
||||
public Color originalBaseColor;
|
||||
public bool emissionEnabled;
|
||||
public Color originalEmissionColor;
|
||||
public float originalEmissionIntensity;
|
||||
|
||||
public ColorSubmodule_BM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ColorSubmodule_BM(GameElement attachedElement) : base(attachedElement)
|
||||
{
|
||||
ColorSubmodule colorSubmodule = (attachedElement as IHaveColorSubmodule).colorSubmodule;
|
||||
this.originalBaseColor = colorSubmodule.originalBaseColor;
|
||||
this.emissionEnabled = colorSubmodule.emissionEnabled;
|
||||
this.originalEmissionColor = colorSubmodule.originalEmissionColor;
|
||||
this.originalEmissionIntensity = colorSubmodule.originalEmissionIntensity;
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
{
|
||||
attachedElement = GameElement_BM.GetElement(attachedElementGuid);
|
||||
(attachedElement as IHaveColorSubmodule).colorSubmodule = new ColorSubmodule(attachedElement,
|
||||
originalBaseColor, emissionEnabled, originalEmissionColor, originalEmissionIntensity);
|
||||
attachedElement.submoduleList.Add((attachedElement as IHaveColorSubmodule).colorSubmodule);
|
||||
}
|
||||
|
||||
public override void DuplicateBM(GameElement attached)
|
||||
{
|
||||
(attached as IHaveColorSubmodule).colorSubmodule = new ColorSubmodule(attached,
|
||||
originalBaseColor, emissionEnabled, originalEmissionColor, originalEmissionIntensity);
|
||||
attached.submoduleList.Add((attached as IHaveColorSubmodule).colorSubmodule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8671bc8338e5d4e93814ee040ac71b87
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,281 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.Editor;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using Sirenix.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
/// <summary>
|
||||
/// 包含效果的次级模块
|
||||
/// </summary>
|
||||
public partial class EffectSubmodule : SubmoduleBase
|
||||
{
|
||||
public Dictionary<string, List<EffectBase>> effectCollection;
|
||||
|
||||
public EffectSubmodule(GameElement attachedGameElement, EffectSubmodulePreset preset = EffectSubmodulePreset.Default)
|
||||
: base(attachedGameElement)
|
||||
{
|
||||
effectCollection = new Dictionary<string, List<EffectBase>>();
|
||||
|
||||
if (preset == EffectSubmodulePreset.Default) //对于默认的效果次级模块,只有Default效果集合
|
||||
{
|
||||
effectCollection.Add("Default", new List<EffectBase>());
|
||||
}
|
||||
else if (preset == EffectSubmodulePreset.Note) //对于Note的效果次级模块,在Note的不同状态下有独立的效果集合
|
||||
{
|
||||
effectCollection.Add("Generate", new List<EffectBase>());
|
||||
effectCollection.Add("GeneralJudge", new List<EffectBase>());
|
||||
effectCollection.Add("Holding", new List<EffectBase>()); //仅用于Hold
|
||||
effectCollection.Add("Perfect", new List<EffectBase>());
|
||||
effectCollection.Add("Good", new List<EffectBase>());
|
||||
effectCollection.Add("Bad", new List<EffectBase>());
|
||||
effectCollection.Add("Miss", new List<EffectBase>());
|
||||
}
|
||||
}
|
||||
|
||||
public EffectSubmodule(GameElement attachedGameElement, Dictionary<string, List<EffectBase_BM>> effectList_BM) : base(attachedGameElement)
|
||||
{
|
||||
effectCollection = new Dictionary<string, List<EffectBase>>();
|
||||
|
||||
foreach (var effect in effectList_BM)
|
||||
{
|
||||
List<EffectBase> effectList = new List<EffectBase>();
|
||||
foreach (var effectBM in effect.Value)
|
||||
{
|
||||
effectList.Add(effectBM.ConvertToGameType());
|
||||
}
|
||||
effectCollection.Add(effect.Key, effectList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class EffectSubmodule
|
||||
{
|
||||
public override void SaveBM()
|
||||
{
|
||||
matchedBM = new EffectSubmodule_BM(attachedGameElement);
|
||||
}
|
||||
|
||||
public override void SetUpInspector()
|
||||
{
|
||||
foreach (var effect in effectCollection)
|
||||
{
|
||||
var container = inspector.GenerateContainer(effect.Key);
|
||||
foreach (var effectBase in effect.Value)
|
||||
{
|
||||
effectBase.SetUpInspector();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class EffectSubmodule
|
||||
{
|
||||
public enum EffectSubmodulePreset
|
||||
{
|
||||
Default,
|
||||
Note,
|
||||
}
|
||||
}
|
||||
|
||||
public interface IHaveEffectSubmodule
|
||||
{
|
||||
public EffectSubmodule effectSubmodule { get; set; }
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public class EffectSubmodule_BM : Submodule_BM
|
||||
{
|
||||
public Dictionary<string, List<EffectBase_BM>> effectCollection;
|
||||
|
||||
public EffectSubmodule_BM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public EffectSubmodule_BM(GameElement attachedElement) : base(attachedElement)
|
||||
{
|
||||
effectCollection = new Dictionary<string, List<EffectBase_BM>>();
|
||||
IHaveEffectSubmodule element = attachedElement as IHaveEffectSubmodule;
|
||||
|
||||
foreach (var effect in element.effectSubmodule.effectCollection)
|
||||
{
|
||||
List<EffectBase_BM> effectList = new List<EffectBase_BM>();
|
||||
foreach (var effectBase in effect.Value)
|
||||
{
|
||||
effectList.Add(effectBase.ConvertToBM());
|
||||
}
|
||||
effectCollection.Add(effect.Key, effectList);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
{
|
||||
attachedElement = GameElement_BM.GetElement(attachedElementGuid);
|
||||
(attachedElement as IHaveEffectSubmodule).effectSubmodule = new EffectSubmodule(attachedElement, effectCollection);
|
||||
attachedElement.submoduleList.Add((attachedElement as IHaveEffectSubmodule).effectSubmodule);
|
||||
}
|
||||
|
||||
public override void DuplicateBM(GameElement attached)
|
||||
{
|
||||
(attached as IHaveEffectSubmodule).effectSubmodule = new EffectSubmodule(attached, effectCollection);
|
||||
attached.submoduleList.Add((attached as IHaveEffectSubmodule).effectSubmodule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class EffectBase : IBaseElement
|
||||
{
|
||||
public enum EffectState
|
||||
{
|
||||
Before = -1,
|
||||
Middle = 0,
|
||||
After = 1,
|
||||
Error = 100
|
||||
}
|
||||
|
||||
public BaseElement_BM matchedBM { get; set; }
|
||||
public Inspector inspector => EditorManager.instance.uiManager.inspector;
|
||||
|
||||
/// <summary>
|
||||
/// 效果的持续时间,如果为0则表示瞬间效果
|
||||
/// </summary>
|
||||
public float effectTime;
|
||||
|
||||
/// <summary>
|
||||
/// 是否是瞬间效果
|
||||
/// </summary>
|
||||
public bool isInstantEffect => effectTime <= 0;
|
||||
|
||||
/// <summary>
|
||||
/// 效果当前的状态
|
||||
/// </summary>
|
||||
public EffectState nowEffectState;
|
||||
|
||||
protected EffectBase()
|
||||
{
|
||||
this.effectTime = 0;
|
||||
this.nowEffectState = EffectState.Before;
|
||||
}
|
||||
|
||||
protected EffectBase(float effectTime)
|
||||
{
|
||||
this.effectTime = effectTime;
|
||||
this.nowEffectState = EffectState.Before;
|
||||
}
|
||||
|
||||
public void SaveBM()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual void UpdateEffect(float triggerTime)
|
||||
{
|
||||
EffectState state = CheckEffectState(triggerTime);
|
||||
|
||||
if (state == EffectState.Before && nowEffectState != EffectState.Before)
|
||||
{
|
||||
nowEffectState = EffectState.Before;
|
||||
Recover();
|
||||
}
|
||||
else if (state == EffectState.Middle)
|
||||
{
|
||||
nowEffectState = EffectState.Middle;
|
||||
Execute();
|
||||
}
|
||||
else if (state == EffectState.After && nowEffectState != EffectState.After)
|
||||
{
|
||||
nowEffectState = EffectState.After;
|
||||
Adjust();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual EffectState CheckEffectState(float triggerTime)
|
||||
{
|
||||
float songTime = EditorManager.instance.songInformation.songTime;
|
||||
|
||||
if (songTime < triggerTime)
|
||||
{
|
||||
return EffectState.Before;
|
||||
}
|
||||
|
||||
if (songTime >= triggerTime &&
|
||||
songTime <= triggerTime + effectTime)
|
||||
{
|
||||
return EffectState.Middle;
|
||||
}
|
||||
|
||||
if (songTime > triggerTime + effectTime)
|
||||
{
|
||||
return EffectState.After;
|
||||
}
|
||||
|
||||
return EffectState.Error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在效果的持续时间内,触发这个方法
|
||||
/// </summary>
|
||||
public virtual void Execute()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 如果是非瞬间效果,在效果完成后,触发这个方法;
|
||||
/// 如果是瞬间效果,则此方法即为Execute。原有的Execute方法不被调用。
|
||||
/// </summary>
|
||||
public virtual void Adjust()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 如果时间轴回退到效果的触发时间之前,则触发这个方法
|
||||
/// </summary>
|
||||
public virtual void Recover()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为存档类
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract EffectBase_BM ConvertToBM();
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public abstract void SetUpInspector();
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public abstract class EffectBase_BM
|
||||
{
|
||||
public float effectTime;
|
||||
|
||||
public EffectBase_BM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public EffectBase_BM(float effectTime)
|
||||
{
|
||||
this.effectTime = effectTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为游戏类
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract EffectBase ConvertToGameType();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67578ca8780234f6d9108a4ea88a5c82
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.Editor;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public abstract class SubmoduleBase : IBaseElement
|
||||
{
|
||||
public GameElement attachedGameElement;
|
||||
|
||||
public BaseElement_BM matchedBM { get; set; }
|
||||
|
||||
public Inspector inspector => EditorManager.instance.uiManager.inspector;
|
||||
|
||||
public SubmoduleBase(GameElement attachedGameElement)
|
||||
{
|
||||
this.attachedGameElement = attachedGameElement;
|
||||
}
|
||||
|
||||
public virtual void InitialRefresh()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public abstract void SaveBM();
|
||||
|
||||
public virtual void OnDelete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void Delete()
|
||||
{
|
||||
attachedGameElement.submoduleList.Remove(this);
|
||||
}
|
||||
|
||||
public virtual void SetUpInspector()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void Refresh()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public abstract class Submodule_BM : BaseElement_BM
|
||||
{
|
||||
[System.NonSerialized] public GameElement attachedElement; //存档类对应的游戏物体
|
||||
public Guid attachedElementGuid;
|
||||
|
||||
public Submodule_BM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Submodule_BM(GameElement attachedElement)
|
||||
{
|
||||
this.attachedElement = attachedElement;
|
||||
attachedElementGuid = attachedElement.elementGuid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制物体
|
||||
/// </summary>
|
||||
/// <param name="attached">(对于物体)父物体,(对于次级模块)或挂载物体</param>
|
||||
public abstract void DuplicateBM(GameElement attached);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07275dc5f06cf4169bd386786acff3a4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,146 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public partial class TimeDurationSubmodule : SubmoduleBase
|
||||
{
|
||||
public bool isOverridingDuration; //是否手动设置了时间区间,开启时,子物体的时间区间将被忽略,且在自动计算区间时跳过此模块
|
||||
public float startTime, endTime; //起止时间
|
||||
|
||||
public TimeDurationSubmodule(GameElement attachedGameElement) : base(attachedGameElement)
|
||||
{
|
||||
isOverridingDuration = false;
|
||||
startTime = -32767;//TODO: 换为-delay
|
||||
endTime = 32767;//TODO: 换为songLength
|
||||
}
|
||||
|
||||
public TimeDurationSubmodule(GameElement attachedGameElement, bool isOverridingDuration, float startTime, float endTime) : base(attachedGameElement)
|
||||
{
|
||||
this.isOverridingDuration = isOverridingDuration;
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public bool CheckTimeInDuration(float time, float offset = 0.2f)
|
||||
{
|
||||
return time >= startTime - offset && time <= endTime + offset;
|
||||
}
|
||||
|
||||
public void SetDuration(float startTime, float endTime)
|
||||
{
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
this.isOverridingDuration = true;
|
||||
}
|
||||
|
||||
public void SetDuration(params FlexibleFloat[] flexibleFloats)
|
||||
{
|
||||
List<float> startTimes = new List<float>();
|
||||
List<float> endTimes = new List<float>();
|
||||
|
||||
foreach (FlexibleFloat flexibleFloat in flexibleFloats)
|
||||
{
|
||||
flexibleFloat.Sort();
|
||||
|
||||
if (flexibleFloat.animations.Count > 0)
|
||||
{
|
||||
startTimes.Add(flexibleFloat.animations[0].startTime);
|
||||
endTimes.Add(flexibleFloat.animations[^1].endTime);
|
||||
}
|
||||
}
|
||||
|
||||
startTime = startTimes.Min();
|
||||
endTime = endTimes.Max();
|
||||
}
|
||||
|
||||
public void SetDurationFromChildren(List<TimeDurationSubmodule> children)
|
||||
{
|
||||
List<float2> durations = new List<float2>();
|
||||
|
||||
if (children.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
durations.Add(new float2(child.startTime, child.endTime));
|
||||
}
|
||||
|
||||
startTime = durations.Min(duration => duration.x);
|
||||
endTime = durations.Max(duration => duration.y);
|
||||
}
|
||||
|
||||
public override void SaveBM()
|
||||
{
|
||||
matchedBM = new TimeDurationSubmodule_BM(attachedGameElement);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class TimeDurationSubmodule
|
||||
{
|
||||
public override void SetUpInspector()
|
||||
{
|
||||
var container = inspector.GenerateContainer("Time Duration");
|
||||
var overrideToggle = inspector.GenerateToggle(this, container, "Override Duration", nameof(isOverridingDuration));
|
||||
var startTimeInputField = inspector.GenerateInputField(this, container, "Start Time", nameof(startTime));
|
||||
var endTimeInputField = inspector.GenerateInputField(this, container, "End Time", nameof(endTime));
|
||||
|
||||
void SetInputFieldInteractable(bool interactable)
|
||||
{
|
||||
startTimeInputField.inputField.interactable = interactable;
|
||||
endTimeInputField.inputField.interactable = interactable;
|
||||
}
|
||||
|
||||
SetInputFieldInteractable(isOverridingDuration);
|
||||
overrideToggle.AddListenerFunction(SetInputFieldInteractable);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public interface IHaveTimeDurationSubmodule
|
||||
{
|
||||
public TimeDurationSubmodule timeDurationSubmodule { get; set; }
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public class TimeDurationSubmodule_BM : Submodule_BM
|
||||
{
|
||||
public bool isOverridingDuration;
|
||||
public float startTime, endTime;
|
||||
|
||||
public TimeDurationSubmodule_BM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public TimeDurationSubmodule_BM(GameElement attachedElement) : base(attachedElement)
|
||||
{
|
||||
TimeDurationSubmodule timeDurationSubmodule = (attachedElement as IHaveTimeDurationSubmodule).timeDurationSubmodule;
|
||||
isOverridingDuration = timeDurationSubmodule.isOverridingDuration;
|
||||
startTime = timeDurationSubmodule.startTime;
|
||||
endTime = timeDurationSubmodule.endTime;
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
{
|
||||
attachedElement = GameElement_BM.GetElement(attachedElementGuid);
|
||||
(attachedElement as IHaveTimeDurationSubmodule).timeDurationSubmodule = new TimeDurationSubmodule(attachedElement, isOverridingDuration, startTime, endTime);
|
||||
attachedElement.submoduleList.Add((attachedElement as IHaveTimeDurationSubmodule).timeDurationSubmodule);
|
||||
}
|
||||
|
||||
public override void DuplicateBM(GameElement attached)
|
||||
{
|
||||
(attached as IHaveTimeDurationSubmodule).timeDurationSubmodule = new TimeDurationSubmodule(attached, isOverridingDuration, startTime, endTime);
|
||||
attached.submoduleList.Add((attached as IHaveTimeDurationSubmodule).timeDurationSubmodule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d84c0a008a0e7478b91b1cbd5f0f5f74
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,211 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using UniRx;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class TransformSubmodule : SubmoduleBase
|
||||
{
|
||||
public Vector3 originalPosition;
|
||||
public Vector3 originalEulerAngles;
|
||||
public Vector3 originalScale;
|
||||
|
||||
public List<Vector3> positionOffset;
|
||||
public List<Vector3> eulerAnglesOffset;
|
||||
public List<Vector3> scaleOffset;
|
||||
|
||||
public Vector3 currentPosition;
|
||||
public Vector3 currentEulerAngles;
|
||||
public Vector3 currentScale;
|
||||
|
||||
public bool positionDirtyMark;
|
||||
public bool eulerAnglesDirtyMark;
|
||||
public bool scaleDirtyMark;
|
||||
|
||||
public bool eulerAnglesOffsetLock;
|
||||
|
||||
|
||||
public TransformSubmodule(GameElement attachedGameElement) : base(attachedGameElement)
|
||||
{
|
||||
this.originalPosition = Vector3.zero;
|
||||
this.originalEulerAngles = Vector3.zero;
|
||||
this.originalScale = Vector3.one;
|
||||
|
||||
positionOffset = new List<Vector3>();
|
||||
eulerAnglesOffset = new List<Vector3>();
|
||||
scaleOffset = new List<Vector3>();
|
||||
|
||||
currentPosition = Vector3.zero;
|
||||
currentEulerAngles = Vector3.zero;
|
||||
currentScale = Vector3.one;
|
||||
|
||||
positionDirtyMark = false;
|
||||
eulerAnglesDirtyMark = false;
|
||||
scaleDirtyMark = false;
|
||||
|
||||
eulerAnglesOffsetLock = false;
|
||||
|
||||
// (attachedGameElement as IHaveTransformSubmodule).SetTransformObserver();
|
||||
}
|
||||
|
||||
public TransformSubmodule(GameElement attachedGameElement,
|
||||
Vector3 originalPosition, Vector3 originalEulerAngles, Vector3 originalScale) : base(attachedGameElement)
|
||||
{
|
||||
this.originalPosition = originalPosition;
|
||||
this.originalEulerAngles = originalEulerAngles;
|
||||
this.originalScale = originalScale;
|
||||
|
||||
positionOffset = new List<Vector3>();
|
||||
eulerAnglesOffset = new List<Vector3>();
|
||||
scaleOffset = new List<Vector3>();
|
||||
|
||||
currentPosition = originalPosition;
|
||||
currentEulerAngles = originalEulerAngles;
|
||||
currentScale = originalScale;
|
||||
|
||||
positionDirtyMark = false;
|
||||
eulerAnglesDirtyMark = false;
|
||||
scaleDirtyMark = false;
|
||||
|
||||
eulerAnglesOffsetLock = false;
|
||||
|
||||
// (attachedGameElement as IHaveTransformSubmodule).SetTransformObserver();
|
||||
}
|
||||
|
||||
public override void SaveBM()
|
||||
{
|
||||
matchedBM = new TransformSubmodule_BM(attachedGameElement);
|
||||
}
|
||||
|
||||
public override void SetUpInspector()
|
||||
{
|
||||
var container = inspector.GenerateContainer("Transform");
|
||||
var originalPosInputField =
|
||||
inspector.GenerateVec3InputField(this, container, "Start Position", nameof(originalPosition));
|
||||
var originalRotInputField =
|
||||
inspector.GenerateVec3InputField(this, container, "Start Rotation", nameof(originalEulerAngles));
|
||||
var originalScaleInputField =
|
||||
inspector.GenerateVec3InputField(this, container, "Start Scale", nameof(originalScale));
|
||||
var currentPosText =
|
||||
inspector.GenerateText(this, container, "Current Position", nameof(currentPosition), true);
|
||||
var currentRotText =
|
||||
inspector.GenerateText(this, container, "Current Rotation", nameof(currentEulerAngles), true);
|
||||
var currentScaleText =
|
||||
inspector.GenerateText(this, container, "Current Scale", nameof(currentScale), true);
|
||||
}
|
||||
|
||||
public override void Refresh()
|
||||
{
|
||||
positionDirtyMark = true;
|
||||
eulerAnglesDirtyMark = true;
|
||||
scaleDirtyMark = true;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IHaveTransformSubmodule
|
||||
{
|
||||
TransformSubmodule transformSubmodule { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置物体Transform的监听,顺序为Scale -> EulerAngles -> Position
|
||||
/// 如果有一些特殊的物体(例如Camera,ElementFolder),需要自定义监听,可以重写这个方法
|
||||
/// </summary>
|
||||
public void SetTransformObserver()
|
||||
{
|
||||
GameElement attachedGameElement = transformSubmodule.attachedGameElement;
|
||||
|
||||
Observable.EveryUpdate().Subscribe(_ =>
|
||||
{
|
||||
if (transformSubmodule == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (transformSubmodule.scaleDirtyMark)
|
||||
{
|
||||
Vector3 offset = Vector3.zero;
|
||||
foreach (Vector3 scaleOffset in transformSubmodule.scaleOffset)
|
||||
{
|
||||
offset += scaleOffset;
|
||||
}
|
||||
|
||||
transformSubmodule.currentScale = transformSubmodule.originalScale + offset;
|
||||
attachedGameElement.transform.localScale = transformSubmodule.currentScale;
|
||||
transformSubmodule.scaleDirtyMark = false;
|
||||
}
|
||||
|
||||
if (transformSubmodule.eulerAnglesDirtyMark)
|
||||
{
|
||||
Vector3 offset = Vector3.zero;
|
||||
foreach (Vector3 eulerOffset in transformSubmodule.eulerAnglesOffset)
|
||||
{
|
||||
offset += eulerOffset;
|
||||
}
|
||||
|
||||
transformSubmodule.currentEulerAngles = transformSubmodule.originalEulerAngles + offset;
|
||||
attachedGameElement.transform.localEulerAngles = transformSubmodule.currentEulerAngles;
|
||||
transformSubmodule.eulerAnglesDirtyMark = false;
|
||||
}
|
||||
|
||||
if (transformSubmodule.positionDirtyMark)
|
||||
{
|
||||
Vector3 offset = Vector3.zero;
|
||||
foreach (Vector3 posOffset in transformSubmodule.positionOffset)
|
||||
{
|
||||
offset += posOffset;
|
||||
}
|
||||
|
||||
transformSubmodule.currentPosition = transformSubmodule.originalPosition + offset;
|
||||
attachedGameElement.transform.localPosition = transformSubmodule.currentPosition;
|
||||
transformSubmodule.positionDirtyMark = false;
|
||||
}
|
||||
|
||||
transformSubmodule.scaleOffset.Clear();
|
||||
transformSubmodule.eulerAnglesOffset.Clear();
|
||||
transformSubmodule.positionOffset.Clear();
|
||||
}).AddTo(attachedGameElement);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public class TransformSubmodule_BM : Submodule_BM
|
||||
{
|
||||
public Vector3 originalPosition;
|
||||
public Vector3 originalEulerAngles;
|
||||
public Vector3 originalScale;
|
||||
|
||||
public TransformSubmodule_BM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public TransformSubmodule_BM(GameElement attachedElement) : base(attachedElement)
|
||||
{
|
||||
TransformSubmodule transformSubmodule = (attachedElement as IHaveTransformSubmodule).transformSubmodule;
|
||||
this.originalPosition = transformSubmodule.originalPosition;
|
||||
this.originalEulerAngles = transformSubmodule.originalEulerAngles;
|
||||
this.originalScale = transformSubmodule.originalScale;
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
{
|
||||
attachedElement = GameElement_BM.GetElement(attachedElementGuid);
|
||||
(attachedElement as IHaveTransformSubmodule).transformSubmodule = new TransformSubmodule(attachedElement, originalPosition, originalEulerAngles, originalScale);
|
||||
attachedElement.submoduleList.Add((attachedElement as IHaveTransformSubmodule).transformSubmodule);
|
||||
}
|
||||
|
||||
public override void DuplicateBM(GameElement attached)
|
||||
{
|
||||
(attached as IHaveTransformSubmodule).transformSubmodule = new TransformSubmodule(attached, originalPosition, originalEulerAngles, originalScale);
|
||||
attached.submoduleList.Add((attached as IHaveTransformSubmodule).transformSubmodule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e65eb5e3a5ce94b709db07ff3ea3d1e3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/EditorGame/Base/ProjectFiles.meta
Normal file
8
Assets/Scripts/EditorGame/Base/ProjectFiles.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f915ace2766c54244aab864fb41d5a93
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,79 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class BeatmapContainer : IBaseElement
|
||||
{
|
||||
public List<GameElement> gameElementList;
|
||||
public BaseElement_BM matchedBM { get; set; }
|
||||
|
||||
public BeatmapContainer()
|
||||
{
|
||||
gameElementList = new List<GameElement>();
|
||||
}
|
||||
|
||||
public void SaveBM()
|
||||
{
|
||||
matchedBM = new BeatmapContainer_BM(gameElementList);
|
||||
}
|
||||
|
||||
public void SetUpInspector()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public class BeatmapContainer_BM : BaseElement_BM
|
||||
{
|
||||
public List<BaseElement_BM> elementList;
|
||||
|
||||
public BeatmapContainer_BM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public BeatmapContainer_BM(List<GameElement> gameElementList)
|
||||
{
|
||||
elementList = new List<BaseElement_BM>();
|
||||
|
||||
gameElementList.ForEach(e =>
|
||||
{
|
||||
e.SaveBM();
|
||||
e.submoduleList.RemoveAll(s=>s == null);
|
||||
e.submoduleList.ForEach(s => s.SaveBM());
|
||||
});
|
||||
|
||||
foreach (var gameElement in gameElementList)
|
||||
{
|
||||
elementList.Add(gameElement.matchedBM);
|
||||
elementList.AddRange(gameElement.submoduleList.ConvertAll(submodule => submodule.matchedBM));
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
{
|
||||
EditorManager.instance.beatmapContainer = new BeatmapContainer();
|
||||
|
||||
elementList.ForEach(element =>
|
||||
{
|
||||
if (element is GameElement_BM gameElement)
|
||||
{
|
||||
GameElement_BM.identifier.Add(gameElement.elementGuid, gameElement);
|
||||
}
|
||||
|
||||
element.ExecuteBM();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9388465a0abc4ef2ab1be2c62476fca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.RhythmGame;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class CommandScripts : IBaseElement
|
||||
{
|
||||
List<string> commandList;
|
||||
public BaseElement_BM matchedBM { get; set; }
|
||||
|
||||
public CommandScripts(List<string> commandList)
|
||||
{
|
||||
this.commandList = commandList;
|
||||
}
|
||||
|
||||
public void SaveBM()
|
||||
{
|
||||
matchedBM = new CommandScripts_BM(commandList);
|
||||
}
|
||||
|
||||
public void SetUpInspector()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public class CommandScripts_BM : BaseElement_BM
|
||||
{
|
||||
public List<string> commandList;
|
||||
|
||||
public CommandScripts_BM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public CommandScripts_BM(List<string> commandList)
|
||||
{
|
||||
this.commandList = commandList;
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
{
|
||||
EditorManager.instance.commandScripts = new CommandScripts(commandList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 687470d59e4c04f6ea0bac268600ed33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,90 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class ProjectInformation : IBaseElement
|
||||
{
|
||||
public string projectName;
|
||||
public string creatorName;
|
||||
public string editorVersion;
|
||||
public string createTime;
|
||||
public string lastSaveTime;
|
||||
public List<string> selectedThemeBundleList;
|
||||
|
||||
public string projectPath;
|
||||
public BaseElement_BM matchedBM { get; set; }
|
||||
|
||||
public string peojectInfoPath => projectPath + "/ProjectInfo.json";
|
||||
public string songInfoPath => projectPath + "/SongInfo.json";
|
||||
public string songPath => projectPath + EditorManager.instance.songInformation.songName + ".wav";
|
||||
public string beatmapPath => projectPath + "/Beatmap.json";
|
||||
public string CommandScriptsPath => projectPath + "/CommandScripts.json";
|
||||
|
||||
public ProjectInformation(string projectName, string creatorName, string editorVersion,
|
||||
string createTime, string lastSaveTime, List<string> selectedThemeBundleList)
|
||||
{
|
||||
this.projectName = projectName;
|
||||
this.creatorName = creatorName;
|
||||
this.editorVersion = editorVersion;
|
||||
this.createTime = createTime;
|
||||
this.lastSaveTime = lastSaveTime;
|
||||
this.selectedThemeBundleList = selectedThemeBundleList;
|
||||
|
||||
projectPath = Application.streamingAssetsPath + "/Projects/" + projectName;
|
||||
}
|
||||
|
||||
public void SaveBM()
|
||||
{
|
||||
matchedBM = new ProjectInformation_BM(projectName, creatorName, editorVersion,
|
||||
createTime, lastSaveTime, selectedThemeBundleList);
|
||||
}
|
||||
|
||||
public void SetUpInspector()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public class ProjectInformation_BM : BaseElement_BM
|
||||
{
|
||||
public string projectName;
|
||||
public string creatorName;
|
||||
public string editorVersion;
|
||||
public string createTime;
|
||||
public string lastSaveTime;
|
||||
public List<string> selectedThemeBundleList;
|
||||
|
||||
public ProjectInformation_BM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ProjectInformation_BM(string projectName, string creatorName, string editorVersion,
|
||||
string createTime, string lastSaveTime, List<string> selectedThemeBundleList)
|
||||
{
|
||||
this.projectName = projectName;
|
||||
this.creatorName = creatorName;
|
||||
this.editorVersion = editorVersion;
|
||||
this.createTime = createTime;
|
||||
this.lastSaveTime = lastSaveTime;
|
||||
this.selectedThemeBundleList = selectedThemeBundleList;
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
{
|
||||
EditorManager.instance.projectInformation = new ProjectInformation(projectName,
|
||||
creatorName, editorVersion, createTime, lastSaveTime, selectedThemeBundleList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4043fbd5e364142a0ab0b42ca9b50076
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class SongInformation : IBaseElement
|
||||
{
|
||||
public AudioClip song; //曲目
|
||||
public string songName;
|
||||
public string songLocation; //曲名
|
||||
public float bpm; //每分钟节拍数
|
||||
public float delay; //设定音乐和谱面延迟Delay秒后开始,在延迟中,SongPosition为负数。
|
||||
|
||||
public float songTime;
|
||||
public float songBeat => songTime / 60 * bpm;
|
||||
|
||||
public BaseElement_BM matchedBM { get; set; }
|
||||
|
||||
public SongInformation(string songName, float bpm, float delay)
|
||||
{
|
||||
this.songName = songName;
|
||||
this.bpm = bpm;
|
||||
this.delay = delay;
|
||||
songLocation = EditorManager.instance.projectInformation.projectPath + "/" + songName + ".wav";
|
||||
Debug.Log("Loading song from " + songLocation + " " + ES3.FileExists(songLocation));
|
||||
song = ES3.LoadAudio(songLocation, AudioType.WAV);
|
||||
}
|
||||
|
||||
public void SaveBM()
|
||||
{
|
||||
matchedBM = new SongInformation_BM(songName, bpm, delay);
|
||||
}
|
||||
|
||||
public void SetUpInspector()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public class SongInformation_BM : BaseElement_BM
|
||||
{
|
||||
public string songName;
|
||||
public float bpm;
|
||||
public float delay;
|
||||
|
||||
public SongInformation_BM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public SongInformation_BM(string songName, float bpm, float delay)
|
||||
{
|
||||
this.songName = songName;
|
||||
this.bpm = bpm;
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
{
|
||||
EditorManager.instance.songInformation = new SongInformation(songName, bpm, delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ae6b1e284d194d63afec48f5d6c4ee8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user