基础内容

必要插件安装
缓动曲线和动画基础
ElementFolder,Track与其次级模块,PathNode重构
This commit is contained in:
SoulliesOfficial
2025-01-26 21:10:16 -05:00
parent 40f63dd2bd
commit 8d0abec75f
9320 changed files with 2950357 additions and 0 deletions

View 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;
}
}
}

View File

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

View 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);
}
}
}

View File

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

View 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;
}
}
}

View File

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

View File

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

View 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
}
}
}

View File

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

View File

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

View File

@@ -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);
}
}
}

View File

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

View File

@@ -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;
}
}
}
}

View File

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

View File

@@ -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;
}
}

View File

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

View File

@@ -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的时间来设置
}
}
}

View File

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