基础内容
必要插件安装 缓动曲线和动画基础 ElementFolder,Track与其次级模块,PathNode重构
This commit is contained in:
BIN
Assets/Scripts/.DS_Store
vendored
Normal file
BIN
Assets/Scripts/.DS_Store
vendored
Normal file
Binary file not shown.
8
Assets/Scripts/Animations.meta
Normal file
8
Assets/Scripts/Animations.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 011e3f878bbe944f68b6d335600e3b80
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
Assets/Scripts/Animations/AnimationBase.cs
Normal file
24
Assets/Scripts/Animations/AnimationBase.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public abstract class AnimationBase : BaseElement
|
||||
{
|
||||
public BaseElement targetObject;
|
||||
public FlexibleReturnType animationReturnType;
|
||||
//public ICanHaveAnimation target;
|
||||
|
||||
public void NewInitialize(string elementName, BaseElement targetObject)
|
||||
{
|
||||
base.NewInitialize(elementName);
|
||||
this.targetObject = targetObject;
|
||||
SetParent(this.targetObject);
|
||||
}
|
||||
|
||||
public abstract void UpdateAnimation(float songTime);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Animations/AnimationBase.cs.meta
Normal file
11
Assets/Scripts/Animations/AnimationBase.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8136d0b00cb8049c98eb2b1d40ad0820
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/Animations/Transform.meta
Normal file
8
Assets/Scripts/Animations/Transform.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 469791310ebae4cbbb29b4d818077938
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
114
Assets/Scripts/Animations/Transform/Displacement.cs
Normal file
114
Assets/Scripts/Animations/Transform/Displacement.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dreamteck.Splines;
|
||||
using Lean.Pool;
|
||||
using Unity.Mathematics;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class Displacement : AnimationBase
|
||||
{
|
||||
public TransformSubmodule targetTransformSubmodule;
|
||||
public FlexibleFloat positionX, positionY, positionZ;
|
||||
|
||||
public static Displacement GenerateElement(string elementName, BaseElement targetObject,
|
||||
FlexibleFloat positionX, FlexibleFloat positionY, FlexibleFloat positionZ)
|
||||
{
|
||||
Displacement displacement = LeanPool.Spawn(new GameObject()).AddComponent<Displacement>();//TODO: 替换 new GameObject();
|
||||
|
||||
displacement.NewInitialize(elementName, targetObject);
|
||||
|
||||
displacement.positionX = positionX;
|
||||
displacement.positionY = positionY;
|
||||
displacement.positionZ = positionZ;
|
||||
displacement.animationReturnType = FlexibleReturnType.Before;
|
||||
|
||||
if (targetObject.transformSubmodule != null)
|
||||
{
|
||||
displacement.targetTransformSubmodule = targetObject.transformSubmodule;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.Exception("Target object does not have a TransformSubmodule");
|
||||
}
|
||||
|
||||
displacement.SetTimeDuration();
|
||||
|
||||
return displacement;
|
||||
}
|
||||
|
||||
public override void SetTimeDuration()
|
||||
{
|
||||
positionX.Sort();
|
||||
positionY.Sort();
|
||||
positionZ.Sort();
|
||||
|
||||
List<float> startTimes = new List<float>();
|
||||
List<float> endTimes = new List<float>();
|
||||
|
||||
if (positionX.animations.Count > 0)
|
||||
{
|
||||
startTimes.Add(positionX.animations[0].startTime);
|
||||
endTimes.Add(positionX.animations[^1].endTime);
|
||||
}
|
||||
|
||||
if (positionY.animations.Count > 0)
|
||||
{
|
||||
startTimes.Add(positionY.animations[0].startTime);
|
||||
endTimes.Add(positionY.animations[^1].endTime);
|
||||
}
|
||||
|
||||
if (positionZ.animations.Count > 0)
|
||||
{
|
||||
startTimes.Add(positionZ.animations[0].startTime);
|
||||
endTimes.Add(positionZ.animations[^1].endTime);
|
||||
}
|
||||
|
||||
float startTime = startTimes.Min();
|
||||
float endTime = endTimes.Max();
|
||||
|
||||
timeDurationSubmodule = new TimeDurationSubmodule(startTime, endTime);
|
||||
}
|
||||
|
||||
protected void Update()
|
||||
{
|
||||
if (timeDurationSubmodule.CheckTimeInDuration(EditorManager.instance.songModule.songTime))
|
||||
{
|
||||
UpdateAnimation(EditorManager.instance.songModule.songTime);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateAnimation(float songTime)
|
||||
{
|
||||
positionX.UpdateFlexibleFloat(songTime);
|
||||
positionY.UpdateFlexibleFloat(songTime);
|
||||
positionZ.UpdateFlexibleFloat(songTime);
|
||||
|
||||
if (positionX.returnType is FlexibleReturnType.MiddleExecuting ||
|
||||
positionY.returnType is FlexibleReturnType.MiddleExecuting ||
|
||||
positionZ.returnType is FlexibleReturnType.MiddleExecuting)
|
||||
{
|
||||
animationReturnType = FlexibleReturnType.MiddleExecuting;
|
||||
Vector3 currentPosition = new Vector3(positionX.value, positionY.value, positionZ.value);
|
||||
targetTransformSubmodule.positionOffset.Add(currentPosition);
|
||||
targetTransformSubmodule.positionDirtyMark = true;
|
||||
}
|
||||
|
||||
//本体使用,用于判断动画是否结束
|
||||
// else if (positionX.returnType is FlexibleReturnType.After or FlexibleReturnType.None &&
|
||||
// positionY.returnType is FlexibleReturnType.After or FlexibleReturnType.None &&
|
||||
// positionZ.returnType is FlexibleReturnType.After or FlexibleReturnType.None)
|
||||
// {
|
||||
// animationReturnType = FlexibleReturnType.After;
|
||||
// float3 currentPosition = new float3(positionX.value, positionY.value, positionZ.value);
|
||||
// targetTransformSubmodule.positionOffset.Add(currentPosition);
|
||||
// targetTransformSubmodule.positionDirtyMark = true;
|
||||
// Destroy(gameObject);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Animations/Transform/Displacement.cs.meta
Normal file
11
Assets/Scripts/Animations/Transform/Displacement.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30dde730c51f742719fcc5c36eb811e5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/Base.meta
Normal file
8
Assets/Scripts/Base.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf41da2409cb34cd7b2d92548a04b8a3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
93
Assets/Scripts/Base/BaseElement.cs
Normal file
93
Assets/Scripts/Base/BaseElement.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
[System.Serializable]
|
||||
public abstract partial class BaseElement : SerializedMonoBehaviour
|
||||
{
|
||||
//物体名
|
||||
public string elementName;
|
||||
|
||||
//序列号
|
||||
public int serialNumber;
|
||||
|
||||
//标识 GUID
|
||||
public Guid elementGuid;
|
||||
|
||||
//存档
|
||||
//public BaseElement_BM matchedBM;
|
||||
|
||||
//父游戏物体
|
||||
public BaseElement parentElement;
|
||||
|
||||
//子物体列表
|
||||
public List<BaseElement> childElementList = new List<BaseElement>();
|
||||
|
||||
//次级模块
|
||||
public TimeDurationSubmodule timeDurationSubmodule;
|
||||
public TransformSubmodule transformSubmodule;
|
||||
|
||||
/// <summary>
|
||||
/// 首次初始化
|
||||
/// </summary>
|
||||
/// <param name="name">物体名</param>
|
||||
public virtual void NewInitialize(string name)
|
||||
{
|
||||
this.elementName = name;
|
||||
this.elementGuid = Guid.NewGuid();
|
||||
//GameManager.beatMapContainer.beatMapElementList.Add(this);
|
||||
//serialNumber = totalSerialNumber++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在所有物体生成完毕后,执行的初始化方法
|
||||
/// </summary>
|
||||
public virtual void AfterInitialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新物体的状态
|
||||
/// </summary>
|
||||
public virtual void Refresh()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置父物体
|
||||
/// </summary>
|
||||
/// <param name="parentElement">父物体</param>
|
||||
public void SetParent(BaseElement parentElement)
|
||||
{
|
||||
if (parentElement != null)
|
||||
{
|
||||
parentElement.childElementList.Add(this);
|
||||
this.parentElement = parentElement;
|
||||
transform.SetParent(parentElement.transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract partial class BaseElement
|
||||
{
|
||||
public virtual void SetTimeDuration()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[Button("Apply Time Duration From Child")]
|
||||
public void ApplyTimeDuration()
|
||||
{
|
||||
childElementList.ForEach(x => x.ApplyTimeDuration());
|
||||
|
||||
timeDurationSubmodule?.SetDurationFromChildren(childElementList.Select(x=>x.timeDurationSubmodule).ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Base/BaseElement.cs.meta
Normal file
11
Assets/Scripts/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/Base/EaseCurve.meta
Normal file
8
Assets/Scripts/Base/EaseCurve.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fda5a36c77610481e976e5d7ceb764ab
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
397
Assets/Scripts/Base/EaseCurve/EaseCurve.cs
Normal file
397
Assets/Scripts/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/Base/EaseCurve/EaseCurve.cs.meta
Normal file
11
Assets/Scripts/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/Base/FlexibleTypes.meta
Normal file
8
Assets/Scripts/Base/FlexibleTypes.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6924511d06874727a50bcbd03bc326a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
234
Assets/Scripts/Base/FlexibleTypes/FlexibleFloat.cs
Normal file
234
Assets/Scripts/Base/FlexibleTypes/FlexibleFloat.cs
Normal file
@@ -0,0 +1,234 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Burst;
|
||||
using Unity.Collections;
|
||||
using Unity.Jobs;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
|
||||
namespace Ichni
|
||||
{
|
||||
[System.Serializable]
|
||||
public class AnimatedFloat : IComparable<AnimatedFloat>
|
||||
{
|
||||
public float startValue, endValue; //起止值
|
||||
public float differenceValue; //差值
|
||||
public float startTime, endTime; //起止时间
|
||||
public float totalTime; //总时间
|
||||
public AnimationCurveType animationCurveType; //动画曲线类型
|
||||
|
||||
public AnimatedFloat(float startTime, float endTime, float startValue, float endValue, AnimationCurveType animationCurveType)
|
||||
{
|
||||
this.startValue = startValue;
|
||||
this.endValue = endValue;
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
totalTime = endTime - startTime;
|
||||
differenceValue = endValue - startValue;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// [BurstCompile]
|
||||
// public void UpdateFlexibleFloat(float nowTime)
|
||||
// {
|
||||
// var animationData = new NativeArray<AnimatedFloat>(animations.ToArray(), Allocator.TempJob);
|
||||
// var result = new NativeArray<float>(1, Allocator.TempJob);
|
||||
// var returnTypeResult = new NativeArray<FlexibleReturnType>(1, Allocator.TempJob);
|
||||
//
|
||||
// var job = new FlexibleFloatJob
|
||||
// {
|
||||
// nowTime = nowTime,
|
||||
// animationData = animationData,
|
||||
// result = result,
|
||||
// returnTypeResult = returnTypeResult
|
||||
// };
|
||||
//
|
||||
// var handle = job.Schedule();
|
||||
// handle.Complete();
|
||||
//
|
||||
// value = result[0];
|
||||
// returnType = returnTypeResult[0];
|
||||
//
|
||||
// animationData.Dispose();
|
||||
// result.Dispose();
|
||||
// returnTypeResult.Dispose();
|
||||
// }
|
||||
|
||||
}
|
||||
/*
|
||||
[BurstCompile]
|
||||
struct FlexibleFloatJob : IJob
|
||||
{
|
||||
public float nowTime;
|
||||
[ReadOnly] public NativeArray<AnimatedFloat> animationData;
|
||||
public NativeArray<float> result;
|
||||
public NativeArray<FlexibleReturnType> returnTypeResult;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
FlexibleReturnType currentReturnType = FlexibleReturnType.None;
|
||||
float outputValue = 0;
|
||||
|
||||
if(animationData.Length == 0)
|
||||
{
|
||||
result[0] = outputValue;
|
||||
returnTypeResult[0] = currentReturnType;
|
||||
return;
|
||||
}
|
||||
|
||||
if (nowTime < animationData[0].startTime)
|
||||
{
|
||||
outputValue = animationData[0].startValue;
|
||||
currentReturnType = FlexibleReturnType.Before;
|
||||
}
|
||||
else if (nowTime > animationData[animationData.Length - 1].endTime)
|
||||
{
|
||||
outputValue = animationData[animationData.Length - 1].endValue;
|
||||
currentReturnType = FlexibleReturnType.After;
|
||||
}
|
||||
|
||||
for (int i = 0; i < animationData.Length; i++)
|
||||
{
|
||||
var anim = animationData[i];
|
||||
|
||||
if (nowTime >= anim.startTime && nowTime <= anim.endTime)
|
||||
{
|
||||
float nowPercent = AnimationCurveEvaluator.Evaluate(anim.animationCurveType,(nowTime - anim.startTime) / anim.totalTime);
|
||||
outputValue = anim.startValue + nowPercent * anim.differenceValue;
|
||||
currentReturnType = FlexibleReturnType.MiddleExecuting;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentReturnType == FlexibleReturnType.None)
|
||||
{
|
||||
currentReturnType = FlexibleReturnType.MiddleInterval;
|
||||
}
|
||||
|
||||
result[0] = outputValue;
|
||||
returnTypeResult[0] = currentReturnType;
|
||||
}
|
||||
|
||||
}*/
|
||||
}
|
||||
11
Assets/Scripts/Base/FlexibleTypes/FlexibleFloat.cs.meta
Normal file
11
Assets/Scripts/Base/FlexibleTypes/FlexibleFloat.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42c83e2f698b543f98d2cfcfb1ac5228
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
15
Assets/Scripts/Base/FlexibleTypes/FlexibleMain.cs
Normal file
15
Assets/Scripts/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 //动画结束后
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Base/FlexibleTypes/FlexibleMain.cs.meta
Normal file
11
Assets/Scripts/Base/FlexibleTypes/FlexibleMain.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cad422c05863e4450a72bebb82f264c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/Base/GeneralSubmodules.meta
Normal file
8
Assets/Scripts/Base/GeneralSubmodules.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f5c439efd47f46888026603e35d5a4e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
41
Assets/Scripts/Base/GeneralSubmodules/ColorSubmodule.cs
Normal file
41
Assets/Scripts/Base/GeneralSubmodules/ColorSubmodule.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public 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(Color originalBaseColor)
|
||||
{
|
||||
this.originalBaseColor = originalBaseColor;
|
||||
this.emissionEnabled = false;
|
||||
this.originalEmissionColor = Color.black;
|
||||
this.originalEmissionIntensity = 0;
|
||||
}
|
||||
|
||||
public ColorSubmodule(Color originalBaseColor, bool emissionEnabled, Color originalEmissionColor, float originalEmissionIntensity)
|
||||
{
|
||||
this.originalBaseColor = originalBaseColor;
|
||||
this.emissionEnabled = emissionEnabled;
|
||||
this.originalEmissionColor = originalEmissionColor;
|
||||
this.originalEmissionIntensity = originalEmissionIntensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Base/GeneralSubmodules/ColorSubmodule.cs.meta
Normal file
11
Assets/Scripts/Base/GeneralSubmodules/ColorSubmodule.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8671bc8338e5d4e93814ee040ac71b87
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Assets/Scripts/Base/GeneralSubmodules/SubmoduleBase.cs
Normal file
14
Assets/Scripts/Base/GeneralSubmodules/SubmoduleBase.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public abstract class SubmoduleBase
|
||||
{
|
||||
public virtual void InitialRefresh()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Base/GeneralSubmodules/SubmoduleBase.cs.meta
Normal file
11
Assets/Scripts/Base/GeneralSubmodules/SubmoduleBase.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07275dc5f06cf4169bd386786acff3a4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class TimeDurationSubmodule: SubmoduleBase
|
||||
{
|
||||
public float startTime, endTime; //起止时间
|
||||
|
||||
public TimeDurationSubmodule()
|
||||
{
|
||||
startTime = 0;
|
||||
endTime = 0;
|
||||
}
|
||||
|
||||
public TimeDurationSubmodule(float startTime, float endTime)
|
||||
{
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public bool CheckTimeInDuration(float time, float offset = 0.2f)
|
||||
{
|
||||
return time >= startTime - offset && time <= endTime + offset;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d84c0a008a0e7478b91b1cbd5f0f5f74
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
68
Assets/Scripts/Base/GeneralSubmodules/TransformSubmodule.cs
Normal file
68
Assets/Scripts/Base/GeneralSubmodules/TransformSubmodule.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
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 UnityAction OnPositionChanged;
|
||||
public UnityAction OnEulerAnglesChanged;
|
||||
public UnityAction OnScaleChanged;
|
||||
|
||||
public TransformSubmodule(Vector3 originalPosition, Vector3 originalEulerAngles, Vector3 originalScale)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
public void SetObserver(BaseElement target)
|
||||
{
|
||||
Observable.EveryUpdate().Subscribe(_ =>
|
||||
{
|
||||
if (positionDirtyMark)
|
||||
{
|
||||
Vector3 offset = Vector3.zero;
|
||||
foreach (var positionOffset in positionOffset)
|
||||
{
|
||||
offset += positionOffset;
|
||||
}
|
||||
currentPosition = originalPosition + offset;
|
||||
positionDirtyMark = false;
|
||||
}
|
||||
positionOffset.Clear();
|
||||
}).AddTo(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e65eb5e3a5ce94b709db07ff3ea3d1e3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/Base/Manager.meta
Normal file
8
Assets/Scripts/Base/Manager.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1497b89f44b5e48a2b790d584735781b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Assets/Scripts/Base/Manager/BasePrefabsCollection.cs
Normal file
14
Assets/Scripts/Base/Manager/BasePrefabsCollection.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
[CreateAssetMenu(fileName = "BasePrefabsCollection", menuName = "Ichni/BasePrefabsCollection", order = 0)]
|
||||
public class BasePrefabsCollection : SerializedScriptableObject
|
||||
{
|
||||
[Title("基础预制体")]
|
||||
public GameObject emptyObject;
|
||||
public GameObject elementFolder;
|
||||
public GameObject track;
|
||||
public GameObject pathNode;
|
||||
}
|
||||
11
Assets/Scripts/Base/Manager/BasePrefabsCollection.cs.meta
Normal file
11
Assets/Scripts/Base/Manager/BasePrefabsCollection.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9bfe18cabd8814ad0b27f5969180c1d2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
44
Assets/Scripts/Base/Manager/EditorManager.cs
Normal file
44
Assets/Scripts/Base/Manager/EditorManager.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.RhythmGame;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni
|
||||
{
|
||||
public class EditorManager : SerializedMonoBehaviour
|
||||
{
|
||||
public static EditorManager instance;
|
||||
|
||||
public SongModule songModule;
|
||||
public BasePrefabsCollection basePrefabs;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
var f0 = ElementFolder.GenerateElement("Folder", null);
|
||||
var t0 = Track.GenerateElement("Track", f0, Vector3.left * 5f);
|
||||
t0.trackPathSubmodule = new TrackPathSubmodule();
|
||||
t0.trackTimeSubmodule = new TrackTimeSubmoduleMovable();
|
||||
t0.trackRendererSubmodule = new TrackRendererSubmoduleAutoOrient();
|
||||
(t0.trackPathSubmodule).NewInitialize(t0, false, Track.TrackSpaceType.Linear, Track.TrackSamplingType.TimeDistributed);
|
||||
(t0.trackTimeSubmodule as TrackTimeSubmoduleMovable).NewInitialize(t0, 0, 1, 1, AnimationCurveType.Linear);
|
||||
(t0.trackRendererSubmodule as TrackRendererSubmoduleAutoOrient).NewInitialize(t0);
|
||||
var p0 = PathNode.GeneratePathNode("PathNode-0", t0, 0, Vector3.zero, Vector3.forward, 1, Color.white);
|
||||
var p1 = PathNode.GeneratePathNode("PathNode-1", t0, 1, Vector3.one * 10f, Vector3.left, 0, Color.white);
|
||||
|
||||
t0.AfterInitialize();
|
||||
}
|
||||
}
|
||||
|
||||
public class SongModule
|
||||
{
|
||||
public float songTime;
|
||||
public float songBeat;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Base/Manager/EditorManager.cs.meta
Normal file
11
Assets/Scripts/Base/Manager/EditorManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d40f46869fc84408ab4870b70e789ef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
232
Assets/Scripts/Base/Manager/ThemeBundleManager.cs
Normal file
232
Assets/Scripts/Base/Manager/ThemeBundleManager.cs
Normal file
@@ -0,0 +1,232 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace Ichni
|
||||
{
|
||||
public class ThemeBundleManager : MonoBehaviour
|
||||
{
|
||||
public static ThemeBundleManager instance;
|
||||
|
||||
public List<ThemeBundleAbstract> themeBundleAbstractList;
|
||||
public List<string> selectedThemeBundleList;
|
||||
public List<ThemeBundle> loadedThemeBundleList;
|
||||
|
||||
public int waitingBundleAmount;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
loadedThemeBundleList = new List<ThemeBundle>();
|
||||
|
||||
AssetBundle.UnloadAllAssetBundles(true);
|
||||
LoadAllThemeBundlesAbstract();
|
||||
|
||||
//DontDestroyOnLoad(gameObject);
|
||||
|
||||
LoadThemeBundle("fundamental");
|
||||
}
|
||||
|
||||
public T GetObject<T>(string themeBundleName, string objectName) where T : class
|
||||
{
|
||||
return loadedThemeBundleList.Find(bundle => bundle.themeBundleName == themeBundleName)?.GetObject<T>(objectName);
|
||||
}
|
||||
|
||||
public void LoadThemeBundles(List<string> list)
|
||||
{
|
||||
foreach (var bundle in list)
|
||||
{
|
||||
LoadThemeBundle(bundle);
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadAllThemeBundlesAbstract()
|
||||
{
|
||||
string uri = Application.streamingAssetsPath + "/ThemeBundles";
|
||||
if (ES3.DirectoryExists(uri))
|
||||
{
|
||||
List<string> allFileList = ES3.GetFiles(uri).ToList();
|
||||
List<string> absList = new List<string>();
|
||||
foreach (var abs in allFileList)
|
||||
{
|
||||
if (abs.EndsWith(".abs"))
|
||||
{
|
||||
absList.Add(abs);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var abs in absList)
|
||||
{
|
||||
ES3Settings settings = new ES3Settings(uri + "/" + abs, ES3.EncryptionType.None);
|
||||
themeBundleAbstractList.Add(ES3.Load<ThemeBundleAbstract>("ThemeBundleAbstract", settings));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadThemeBundle(string themeBundleName)
|
||||
{
|
||||
waitingBundleAmount++;
|
||||
StartCoroutine(LoadThemeBundleCoroutine(themeBundleName));
|
||||
}
|
||||
|
||||
IEnumerator LoadThemeBundleCoroutine(string themeBundleName)
|
||||
{
|
||||
string uri = "";
|
||||
|
||||
if (Application.platform == RuntimePlatform.WindowsEditor ||
|
||||
Application.platform == RuntimePlatform.WindowsPlayer)
|
||||
{
|
||||
uri = Application.streamingAssetsPath + "/ThemeBundles/Windows64/" + themeBundleName;
|
||||
}else if (Application.platform == RuntimePlatform.OSXEditor ||
|
||||
Application.platform == RuntimePlatform.OSXPlayer)
|
||||
{
|
||||
|
||||
uri = Application.streamingAssetsPath + "/ThemeBundles/OSX/" + themeBundleName;
|
||||
}
|
||||
|
||||
UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uri, 0);
|
||||
yield return request.SendWebRequest();
|
||||
AssetBundle bundle = AssetBundle.LoadFromFile(uri);
|
||||
Object[] ob = bundle.LoadAllAssets<Object>();
|
||||
loadedThemeBundleList.Add(new ThemeBundle(themeBundleName));
|
||||
for (int i = 0; i < ob.Length; i++)
|
||||
{
|
||||
if (ob[i].GetType() == typeof(GameObject))
|
||||
{
|
||||
loadedThemeBundleList[^1].assetList_GameObject.Add(ob[i] as GameObject);
|
||||
}
|
||||
else if (ob[i].GetType() == typeof(Material))
|
||||
{
|
||||
loadedThemeBundleList[^1].assetList_Material.Add(ob[i] as Material);
|
||||
}
|
||||
else if (ob[i].GetType() == typeof(Texture2D))
|
||||
{
|
||||
loadedThemeBundleList[^1].assetList_Texture.Add(ob[i] as Texture2D);
|
||||
}
|
||||
else
|
||||
{
|
||||
loadedThemeBundleList[^1].assetList_Other.Add(ob[i]);
|
||||
}
|
||||
}
|
||||
|
||||
yield return new WaitForEndOfFrame();
|
||||
waitingBundleAmount--;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class ThemeBundleAbstract
|
||||
{
|
||||
public string themeBundleName;
|
||||
public List<string> tags;
|
||||
|
||||
public string iconPath;
|
||||
|
||||
public ThemeBundleAbstract()
|
||||
{
|
||||
}
|
||||
|
||||
public ThemeBundleAbstract(string themeBundleName, List<string> tags, string iconPath)
|
||||
{
|
||||
this.themeBundleName = themeBundleName;
|
||||
this.tags = tags;
|
||||
this.iconPath = iconPath;
|
||||
}
|
||||
|
||||
public Texture2D GetIcon()
|
||||
{
|
||||
string uri = Application.streamingAssetsPath + "/" + iconPath;
|
||||
if (ES3.FileExists(uri))
|
||||
{
|
||||
Texture2D sp = ES3.LoadImage(uri);
|
||||
return sp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class ThemeBundle
|
||||
{
|
||||
public string themeBundleName;
|
||||
public List<GameObject> assetList_GameObject;
|
||||
public List<Material> assetList_Material;
|
||||
public List<Texture2D> assetList_Texture;
|
||||
public List<Object> assetList_Other;
|
||||
|
||||
public ThemeBundle(string name)
|
||||
{
|
||||
themeBundleName = name;
|
||||
assetList_GameObject = new List<GameObject>();
|
||||
assetList_Material = new List<Material>();
|
||||
assetList_Texture = new List<Texture2D>();
|
||||
assetList_Other = new List<Object>();
|
||||
}
|
||||
|
||||
public T GetObject<T>(string name)
|
||||
{
|
||||
if (name == "None")
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
T[] assetList;
|
||||
|
||||
if (typeof(T) == typeof(GameObject))
|
||||
{
|
||||
assetList = assetList_GameObject.ToArray() as T[];
|
||||
|
||||
for (int i = 0; i < assetList_GameObject.Count; i++)
|
||||
{
|
||||
if (name == assetList_GameObject[i].name)
|
||||
{
|
||||
return assetList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (typeof(T) == typeof(Material))
|
||||
{
|
||||
assetList = assetList_Material.ToArray() as T[];
|
||||
|
||||
for (int i = 0; i < assetList_Material.Count; i++)
|
||||
{
|
||||
if (name == assetList_Material[i].name)
|
||||
{
|
||||
return assetList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (typeof(T) == typeof(Texture2D))
|
||||
{
|
||||
assetList = assetList_Texture.ToArray() as T[];
|
||||
|
||||
for (int i = 0; i < assetList_Texture.Count; i++)
|
||||
{
|
||||
if (name == assetList_Texture[i].name)
|
||||
{
|
||||
return assetList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assetList = assetList_Other.ToArray() as T[];
|
||||
for (int i = 0; i < assetList_Other.Count; i++)
|
||||
{
|
||||
if (name == assetList_Other[i].name)
|
||||
{
|
||||
return assetList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Base/Manager/ThemeBundleManager.cs.meta
Normal file
11
Assets/Scripts/Base/Manager/ThemeBundleManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d27859adda1341aaa0db8a117d5431c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/Base/ProjectFiles.meta
Normal file
8
Assets/Scripts/Base/ProjectFiles.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f915ace2766c54244aab864fb41d5a93
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Scripts/Base/ProjectFiles/BeatmapContainer.cs
Normal file
18
Assets/Scripts/Base/ProjectFiles/BeatmapContainer.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class BeatmapContainer : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Base/ProjectFiles/BeatmapContainer.cs.meta
Normal file
11
Assets/Scripts/Base/ProjectFiles/BeatmapContainer.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9388465a0abc4ef2ab1be2c62476fca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Scripts/Base/ProjectFiles/CommandScriptContainer.cs
Normal file
18
Assets/Scripts/Base/ProjectFiles/CommandScriptContainer.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class CommandScriptContainer : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 687470d59e4c04f6ea0bac268600ed33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Scripts/Base/ProjectFiles/ProjectInformation.cs
Normal file
18
Assets/Scripts/Base/ProjectFiles/ProjectInformation.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ProjectInformation : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Base/ProjectFiles/ProjectInformation.cs.meta
Normal file
11
Assets/Scripts/Base/ProjectFiles/ProjectInformation.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4043fbd5e364142a0ab0b42ca9b50076
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Scripts/Base/ProjectFiles/SongInformation.cs
Normal file
18
Assets/Scripts/Base/ProjectFiles/SongInformation.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class SongInformation : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Base/ProjectFiles/SongInformation.cs.meta
Normal file
11
Assets/Scripts/Base/ProjectFiles/SongInformation.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ae6b1e284d194d63afec48f5d6c4ee8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/GameElements.meta
Normal file
8
Assets/Scripts/GameElements.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52e718a21001f425680a6ca7fd7558b3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
23
Assets/Scripts/GameElements/ElementFolder.cs
Normal file
23
Assets/Scripts/GameElements/ElementFolder.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Lean.Pool;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class ElementFolder : BaseElement
|
||||
{
|
||||
public static ElementFolder GenerateElement(string name, BaseElement parentElement)
|
||||
{
|
||||
ElementFolder elementFolder = LeanPool.Spawn(EditorManager.instance.basePrefabs.elementFolder).GetComponent<ElementFolder>();
|
||||
|
||||
elementFolder.NewInitialize(name);
|
||||
elementFolder.SetParent(parentElement);
|
||||
//elementFolder.GenerateTab(parentElement);
|
||||
|
||||
return elementFolder;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/GameElements/ElementFolder.cs.meta
Normal file
11
Assets/Scripts/GameElements/ElementFolder.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0892af0ddd15c449d9b1c65248b5dc64
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
71
Assets/Scripts/GameElements/PathNode.cs
Normal file
71
Assets/Scripts/GameElements/PathNode.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Dreamteck.Splines;
|
||||
using Ichni;
|
||||
using Lean.Pool;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public partial class PathNode : BaseElement
|
||||
{
|
||||
public ColorSubmodule colorSubmodule;
|
||||
|
||||
public Track track;
|
||||
public int index;
|
||||
public SplinePoint node;
|
||||
|
||||
public static PathNode GeneratePathNode(string elementName, Track track, int index, Vector3 nodePosition,
|
||||
Vector3 nodeNormal, float nodeSize, Color nodeColor)
|
||||
{
|
||||
PathNode pathNode = LeanPool.Spawn(EditorManager.instance.basePrefabs.pathNode, track.transform).GetComponent<PathNode>();
|
||||
|
||||
pathNode.NewInitialize(elementName, track, index, nodePosition, nodeNormal, nodeSize, nodeColor);
|
||||
|
||||
track.trackPathSubmodule.pathNodeList.Add(pathNode);
|
||||
pathNode.SetParent(track);
|
||||
return pathNode;
|
||||
}
|
||||
|
||||
public void NewInitialize(string elementName, Track track, int index, Vector3 nodePosition,
|
||||
Vector3 nodeNormal, float nodeSize, Color nodeColor)
|
||||
{
|
||||
base.NewInitialize(elementName);
|
||||
this.track = track;
|
||||
this.index = index;
|
||||
|
||||
if (track.trackPathSubmodule.pathNodeList.Count > index)
|
||||
{
|
||||
this.index = track.trackPathSubmodule.pathNodeList.Count;
|
||||
}
|
||||
|
||||
this.transformSubmodule = new TransformSubmodule(nodePosition, Quaternion.LookRotation(nodeNormal, Vector3.up).eulerAngles, Vector3.one * nodeSize);
|
||||
this.colorSubmodule = new ColorSubmodule(nodeColor);
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public override void AfterInitialize()
|
||||
{
|
||||
Refresh();
|
||||
if (track.trackPathSubmodule.pathNodeList.Count > 3)
|
||||
{
|
||||
track.trackPathSubmodule.ClosePath(track.trackPathSubmodule.isClosed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class PathNode
|
||||
{
|
||||
public override void Refresh()
|
||||
{
|
||||
Vector3 position = transformSubmodule.currentPosition;
|
||||
Vector3 normal = Quaternion.Euler(transformSubmodule.currentEulerAngles) * Vector3.up;
|
||||
float size = transformSubmodule.currentScale.x;
|
||||
Color color = colorSubmodule.currentBaseColor;
|
||||
|
||||
node = new SplinePoint(position, Vector3.up, normal, size, color);
|
||||
track.trackPathSubmodule.SetPathNode(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/GameElements/PathNode.cs.meta
Normal file
11
Assets/Scripts/GameElements/PathNode.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09efd164733b64d539127e1d09f6ef5a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
23
Assets/Scripts/GameElements/SubstantialObject.cs
Normal file
23
Assets/Scripts/GameElements/SubstantialObject.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Lean.Pool;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class SubstantialObject : BaseElement
|
||||
{
|
||||
public string themeBundleName, objectName;
|
||||
|
||||
public static SubstantialObject GenerateElement(string elementName, string themeBundleName,
|
||||
string objectName, Vector3 position, Vector3 eulerAngles, Vector3 scale, BaseElement parent,
|
||||
bool isFirstGenerated = true)
|
||||
{
|
||||
GameObject themeBundleObject = ThemeBundleManager.instance.GetObject<GameObject>(themeBundleName, objectName);
|
||||
SubstantialObject substantialObject = LeanPool.Spawn(themeBundleObject, parent.transform).GetComponent<SubstantialObject>();
|
||||
substantialObject.NewInitialize(elementName);
|
||||
|
||||
return substantialObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/GameElements/SubstantialObject.cs.meta
Normal file
11
Assets/Scripts/GameElements/SubstantialObject.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2c7aad5a561545eba2bd0785c33496d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/GameElements/Track.meta
Normal file
8
Assets/Scripts/GameElements/Track.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ce1732fa451f41a7b476ce2b6c82aae
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
79
Assets/Scripts/GameElements/Track/Track.cs
Normal file
79
Assets/Scripts/GameElements/Track/Track.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Lean.Pool;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public partial class Track : BaseElement
|
||||
{
|
||||
public TrackPathSubmodule trackPathSubmodule;
|
||||
public TrackTimeSubmodule trackTimeSubmodule;
|
||||
public TrackRendererSubmodule trackRendererSubmodule;
|
||||
|
||||
public static Track GenerateElement(string elementName, BaseElement parent, Vector3 position)
|
||||
{
|
||||
if (parent == null)
|
||||
{
|
||||
throw new System.Exception("Parent is null");
|
||||
}
|
||||
|
||||
Track track = LeanPool.Spawn(EditorManager.instance.basePrefabs.track, parent.transform).GetComponent<Track>();
|
||||
|
||||
track.NewInitialize(elementName, position);
|
||||
track.SetParent(parent);
|
||||
|
||||
return track;
|
||||
}
|
||||
|
||||
private void NewInitialize(string elementName, Vector3 position)
|
||||
{
|
||||
base.NewInitialize(elementName);
|
||||
timeDurationSubmodule = new TimeDurationSubmodule();
|
||||
transformSubmodule = new TransformSubmodule(position, Vector3.zero, Vector3.one);
|
||||
trackPathSubmodule = null;
|
||||
trackTimeSubmodule = null;
|
||||
trackRendererSubmodule = null;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public override void AfterInitialize()
|
||||
{
|
||||
trackPathSubmodule.path.RebuildImmediate();
|
||||
//Refresh();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (timeDurationSubmodule.CheckTimeInDuration(EditorManager.instance.songModule.songTime))
|
||||
{
|
||||
(trackTimeSubmodule as TrackTimeSubmoduleMovable)?.UpdateTrackPart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Track
|
||||
{
|
||||
public override void Refresh()
|
||||
{
|
||||
transform.localPosition = transformSubmodule.currentPosition;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Track
|
||||
{
|
||||
public enum TrackSpaceType
|
||||
{
|
||||
CatmullRom = 0,
|
||||
BSpline = 1,
|
||||
Linear = 3
|
||||
}
|
||||
|
||||
public enum TrackSamplingType
|
||||
{
|
||||
TimeDistributed = 0,
|
||||
DistanceDistributed = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/GameElements/Track/Track.cs.meta
Normal file
11
Assets/Scripts/GameElements/Track/Track.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d2b6af5deaa046ff89ed3c74bb2ffdc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/GameElements/Track/TrackSubmodules.meta
Normal file
8
Assets/Scripts/GameElements/Track/TrackSubmodules.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8348db51d6bc4d48b37e45339d1aaab
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Dreamteck.Splines;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public partial class TrackPathSubmodule : TrackSubmodule
|
||||
{
|
||||
public SplineComputer path;
|
||||
public List<PathNode> pathNodeList;
|
||||
|
||||
public Track.TrackSpaceType trackSpaceType;
|
||||
public Track.TrackSamplingType trackSamplingType;
|
||||
public bool isClosed;
|
||||
|
||||
public void NewInitialize(Track track, bool isClosed, Track.TrackSpaceType trackSpaceType,
|
||||
Track.TrackSamplingType trackSamplingType)
|
||||
{
|
||||
this.track = track;
|
||||
this.path = track.AddComponent<SplineComputer>();
|
||||
track.trackPathSubmodule = this;
|
||||
this.pathNodeList = new List<PathNode>();
|
||||
this.trackSpaceType = trackSpaceType;
|
||||
this.trackSamplingType = trackSamplingType;
|
||||
this.isClosed = isClosed;
|
||||
|
||||
SetUpSplineComputer(trackSpaceType, trackSamplingType);
|
||||
}
|
||||
}
|
||||
|
||||
public partial class TrackPathSubmodule
|
||||
{
|
||||
private void SetUpSplineComputer(Track.TrackSpaceType trackSpaceType, Track.TrackSamplingType trackSamplingType)
|
||||
{
|
||||
path.type = (Spline.Type)(int)trackSpaceType;
|
||||
path.sampleMode = (SplineComputer.SampleMode)(int)trackSamplingType;
|
||||
path.space = SplineComputer.Space.Local;
|
||||
}
|
||||
|
||||
public void ClosePath(bool close)
|
||||
{
|
||||
if (close)
|
||||
{
|
||||
path.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
path.Break();
|
||||
}
|
||||
|
||||
isClosed = close;
|
||||
}
|
||||
|
||||
public void SetTrackSpaceType(int spaceType)
|
||||
{
|
||||
trackSpaceType = (Track.TrackSpaceType)spaceType;
|
||||
path.type = (Spline.Type)spaceType;
|
||||
}
|
||||
|
||||
public void AddPathNode(PathNode point)
|
||||
{
|
||||
path.SetPoint(pathNodeList.Count, point.node, SplineComputer.Space.Local);
|
||||
|
||||
pathNodeList.Add(point);
|
||||
}
|
||||
|
||||
public void SetPathNode(PathNode point)
|
||||
{
|
||||
path.SetPoint(point.index, point.node, SplineComputer.Space.Local);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e365a28188395451e95f60530805d7ca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Dreamteck.Splines;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class TrackRendererSubmodule : TrackSubmodule
|
||||
{
|
||||
public Track track;
|
||||
public MeshGenerator meshGenerator;
|
||||
public MeshRenderer meshRenderer;
|
||||
}
|
||||
|
||||
public class TrackRendererSubmoduleAutoOrient : TrackRendererSubmodule
|
||||
{
|
||||
public SplineRenderer splineRenderer;
|
||||
|
||||
public void NewInitialize(Track track)
|
||||
{
|
||||
this.track = track;
|
||||
this.track.trackRendererSubmodule = this;
|
||||
this.splineRenderer = track.AddComponent<SplineRenderer>();
|
||||
this.meshGenerator = splineRenderer;
|
||||
this.splineRenderer.spline = track.trackPathSubmodule.path;
|
||||
this.splineRenderer.clipFrom = 0;
|
||||
this.splineRenderer.clipTo = 1;
|
||||
Debug.Log(splineRenderer.clipFrom + " " + splineRenderer.clipTo);
|
||||
this.splineRenderer.color = Color.white;
|
||||
}
|
||||
|
||||
public override void InitialRefresh()
|
||||
{
|
||||
if (track.trackTimeSubmodule is TrackTimeSubmoduleMovable)
|
||||
{
|
||||
splineRenderer.clipFrom = 0;
|
||||
splineRenderer.clipTo = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01fba1b4480fc4988be3f80598f285c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public abstract class TrackSubmodule : SubmoduleBase
|
||||
{
|
||||
public Track track;
|
||||
public bool isUpdating;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d9735a5fb100495d84928630f6e97da
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class TrackTimeSubmodule : TrackSubmodule
|
||||
{
|
||||
public float headPercent, tailPercent;
|
||||
}
|
||||
|
||||
public class TrackTimeSubmoduleMovable : TrackTimeSubmodule
|
||||
{
|
||||
public float trackStartTime;
|
||||
public float trackEndTime;
|
||||
public float trackTotalTime;
|
||||
public float visibleTrackTimeLength;
|
||||
public AnimationCurveType animationCurveType;
|
||||
|
||||
public void NewInitialize(Track track, float trackStartTime, float trackEndTime,
|
||||
float visibleTrackTimeLength, AnimationCurveType animationCurveType)
|
||||
{
|
||||
this.track = track;
|
||||
this.track.trackTimeSubmodule = this;
|
||||
this.trackStartTime = trackStartTime;
|
||||
this.trackEndTime = trackEndTime;
|
||||
this.trackTotalTime = trackEndTime - trackStartTime;
|
||||
this.visibleTrackTimeLength = visibleTrackTimeLength;
|
||||
this.animationCurveType = animationCurveType;
|
||||
track.timeDurationSubmodule.startTime = trackStartTime;
|
||||
track.timeDurationSubmodule.endTime = trackEndTime + visibleTrackTimeLength;
|
||||
}
|
||||
|
||||
public void UpdateTrackPart()
|
||||
{
|
||||
float songTime = EditorManager.instance.songModule.songTime;
|
||||
|
||||
headPercent = GetTrackPercent(songTime);
|
||||
tailPercent = GetTrackPercent(songTime - visibleTrackTimeLength);
|
||||
|
||||
Debug.Log("Head: " + headPercent + " Tail: " + tailPercent);
|
||||
|
||||
if (track.trackRendererSubmodule != null)
|
||||
{
|
||||
track.trackRendererSubmodule.meshGenerator.clipFrom = tailPercent;
|
||||
track.trackRendererSubmodule.meshGenerator.clipTo = headPercent;
|
||||
}
|
||||
}
|
||||
|
||||
private float GetTrackPercent(float songTimeInTime)
|
||||
{
|
||||
float per = AnimationCurveEvaluator.Evaluate(animationCurveType, (songTimeInTime - trackStartTime) / trackTotalTime);
|
||||
return Mathf.Clamp01(per);
|
||||
}
|
||||
}
|
||||
|
||||
public class TrackTimeSubmoduleStatic : TrackTimeSubmodule
|
||||
{
|
||||
public float trackTotalTime;
|
||||
public AnimationCurveType animationCurveType;
|
||||
|
||||
public void NewInitialize(Track track, float trackTotalTime, AnimationCurveType animationCurveType)
|
||||
{
|
||||
this.track = track;
|
||||
this.track.trackTimeSubmodule = this;
|
||||
this.trackTotalTime = trackTotalTime;
|
||||
this.animationCurveType = animationCurveType;
|
||||
this.headPercent = 0;
|
||||
this.tailPercent = 1;
|
||||
track.timeDurationSubmodule.startTime = 0;
|
||||
track.timeDurationSubmodule.endTime = 0;
|
||||
//timeDurationSubmodule 根据下辖Note的时间来设置
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2ed41fffa9a44e6d923a7866af34590
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user