This commit is contained in:
SoulliesOfficial
2025-02-14 22:04:21 -05:00
parent 0bcc843740
commit 934d1b5aba
42 changed files with 5699 additions and 91 deletions

View File

@@ -25,9 +25,9 @@ namespace Ichni.RhythmGame
protected virtual void Update()
{
if (timeDurationSubmodule.CheckTimeInDuration(EditorManager.instance.songModule.songTime))
if (timeDurationSubmodule.CheckTimeInDuration(EditorManager.instance.songInformation.songTime))
{
UpdateAnimation(EditorManager.instance.songModule.songTime);
UpdateAnimation(EditorManager.instance.songInformation.songTime);
}
}
}

View File

@@ -13,9 +13,7 @@ namespace Ichni
public class EditorManager : SerializedMonoBehaviour
{
public static EditorManager instance;
public SongModule songModule;
public ProjectManager projectManager;
public EditorUIManager uiManager;
public EditorSettings editorSettings;
@@ -38,8 +36,8 @@ namespace Ichni
{
//CreateNew();
projectManager.loadManager.Load("TestProject");
AudioSource.PlayClipAtPoint(songInformation.song, Vector3.zero);
uiManager.timeline.musicPlayer.audioSource.clip = songInformation.song;
beatmapContainer.gameElementList.ForEach(gameElement =>
{
if (gameElement is IHaveTransformSubmodule transformedElement)
@@ -55,11 +53,6 @@ namespace Ichni
// projectManager.exportManager.Export();
}
private void Update()
{
songModule.songTime += Time.deltaTime;
}
private void CreateNew()
{
projectManager.GenerateProject("TestProject");
@@ -100,10 +93,4 @@ namespace Ichni
"basic", "BasicNoteTap3D");
}
}
public class SongModule
{
public float songTime;
public float songBeat;
}
}

View File

@@ -13,6 +13,9 @@ namespace Ichni.RhythmGame
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)

View File

@@ -13,6 +13,8 @@ using System.Linq;
using Unity.VisualScripting;
using Ichni.RhythmGame;
using Sirenix.Utilities;
using UnityEngine.InputSystem;
//又在写大粪 ——神币
namespace Ichni.Editor
{
@@ -44,13 +46,13 @@ namespace Ichni.Editor
}catch(Exception e){Debug.LogWarning("WTF Command! "+e);}
}
private void Update(){
if(Input.GetKeyDown(KeyCode.BackQuote)){
if(Keyboard.current.backquoteKey.wasPressedThisFrame){
hierarchy.gameObject.SetActive(isHide);
inspector.gameObject.SetActive(isHide);
isHide=!isHide;
}
if(InputCommand.isFocused){
if(Input.GetKeyDown(KeyCode.DownArrow)){
if(Keyboard.current.downArrowKey.wasPressedThisFrame){
if(historyCommand.Count-1>historycount){
historycount++;
InputCommand.text=historyCommand[historycount];}
@@ -60,7 +62,7 @@ namespace Ichni.Editor
}
}
if(Input.GetKeyDown(KeyCode.UpArrow)&&historycount!=0){
if(Keyboard.current.upArrowKey.wasPressedThisFrame && historycount!=0){
historycount--;
InputCommand.text=historyCommand[historycount];
}

View File

@@ -8,6 +8,7 @@ namespace Ichni.Editor
{
public Hierarchy hierarchy;
public Inspector inspector;
public Timeline timeline;
}
}

View File

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

View File

@@ -0,0 +1,52 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame;
using UnityEngine;
using UnityEngine.UI;
namespace Ichni.Editor
{
public class MusicPlayer : MonoBehaviour
{
public bool isPlaying;
public AudioSource audioSource;
public Button playButton;
public Button pauseButton;
public Button stopButton;
private void Awake()
{
audioSource = GetComponent<AudioSource>();
playButton.onClick.AddListener(PlayMusic);
pauseButton.onClick.AddListener(PauseMusic);
stopButton.onClick.AddListener(StopMusic);
}
public void PlayMusic()
{
isPlaying = true;
Trail.SetAllTrails(true, false);
EditorManager.instance.songInformation.songTime = audioSource.time;
audioSource.Play();
}
public void PauseMusic()
{
isPlaying = false;
Trail.SetAllTrails(false, false);
EditorManager.instance.songInformation.songTime = audioSource.time;
audioSource.Pause();
}
public void StopMusic()
{
isPlaying = false;
Trail.SetAllTrails(false, true);
EditorManager.instance.songInformation.songTime = 0;
audioSource.Stop();
EditorManager.instance.uiManager.timeline.timePointerModule.SetRange(0);
}
}
}

View File

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

View File

@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TimeInfoModule : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

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

View File

@@ -0,0 +1,15 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UniRx;
using UnityEngine;
namespace Ichni.Editor
{
public class TimePointer : MonoBehaviour
{
public TMP_Text intervalUnitText;
public float time;
public int index;
}
}

View File

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

View File

@@ -0,0 +1,216 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame;
using UniRx;
using UnityEngine;
using UnityEngine.Serialization;
namespace Ichni.Editor
{
public partial class TimePointerModule : MonoBehaviour
{
private Timeline timeline => EditorManager.instance.uiManager.timeline;
private SongInformation songInformation => EditorManager.instance.songInformation;
public GameObject timePointerPrefab;
public List<TimePointer> timePointerList;
public RectTransform timePointerArea;
public RectTransform visibleTimePointerArea;
public RectTransform mainTimePointer;
public float intervalUnit;
public float timePointerInterval;
public float sizeNegative, sizePositive;
public int negativePointerAmount, positivePointerAmount, totalPointerAmount;
/// <summary>
/// delay时间区间中(-delay, 0)的距离偏移量
/// </summary>
public float delayDistanceOffset;
public float leftSideSongTime, rightSideSongTime, songTimeDistance;
private void Start()
{
Observable.NextFrame().Subscribe(_ =>
{
timePointerList = new List<TimePointer>();
Initialize(2, 120);
});
}
private void Update()
{
if (timeline.musicPlayer.isPlaying)
{
songInformation.songTime = timeline.musicPlayer.audioSource.time;
SetRange(songInformation.songTime);
}
timePointerList.ForEach(pointer =>
{
bool isActive = pointer.time >= leftSideSongTime && pointer.time <= rightSideSongTime;
pointer.gameObject.SetActive(isActive);
});
}
/// <summary>
/// 初始化所有Timeline指示线
/// </summary>
/// <param name="delay"></param>
/// <param name="bpm"></param>
public void Initialize(float delay, float bpm)
{
timePointerInterval = 30;
ClearPointers();
int beatDivider = 1;
intervalUnit = (60f / bpm) / beatDivider * 1000;
sizeNegative = delay * beatDivider / timeline.timePerBeat;
sizePositive = songInformation.song.length * beatDivider / timeline.timePerBeat;
negativePointerAmount = Mathf.CeilToInt(sizeNegative);
positivePointerAmount = Mathf.CeilToInt(sizePositive);
totalPointerAmount = negativePointerAmount + positivePointerAmount;
timePointerArea.sizeDelta = new Vector2(timePointerInterval * (sizeNegative + sizePositive), 60f);
delayDistanceOffset = timePointerInterval * (negativePointerAmount - sizeNegative);
leftSideSongTime = timeline.beatmapStartTime;
rightSideSongTime = timeline.timePerBeat * (visibleTimePointerArea.rect.width / timePointerInterval);
songTimeDistance = rightSideSongTime;
for (int i = -negativePointerAmount; i <= positivePointerAmount; i++)
{
CreatePointer(beatDivider, i);
}
//ChangeSongTimeDistance(0);
SetRange(timeline.beatmapStartTime);
}
}
public partial class TimePointerModule
{
/// <summary>
/// 设置Timeline的显示区间区间宽度使用当前的区间宽度
/// </summary>
/// <param name="startTime">开始时间,结束时间即(开始时间+区间宽度)</param>
public void SetRange(float startTime)
{
startTime = Mathf.Clamp(startTime, timeline.beatmapStartTime, songInformation.song.length);
timePointerArea.anchoredPosition =
new Vector2((timePointerArea.sizeDelta.x / 2) -
((startTime + songInformation.delay) / timeline.timePerBeat) * timePointerInterval, 0);
float proportion = mainTimePointer.anchoredPosition.x / visibleTimePointerArea.rect.width;
leftSideSongTime = startTime - songTimeDistance * proportion;
rightSideSongTime = startTime + songTimeDistance * (1 - proportion);
}
/// <summary>
/// 生成指示线
/// </summary>
/// <param name="beatDivider">细分X分音符</param>
/// <param name="index"></param>
private void CreatePointer(int beatDivider, int index)
{
TimePointer pointer = Instantiate(timePointerPrefab, timePointerArea).GetComponent<TimePointer>();
timePointerList.Add(pointer);
pointer.index = index;
pointer.GetComponent<RectTransform>().anchoredPosition =
new Vector2((index + negativePointerAmount) * timePointerInterval + 15f - delayDistanceOffset, 0);
pointer.time = index * intervalUnit / 1000f;
pointer.intervalUnitText.text = Mathf.RoundToInt(index * intervalUnit).ToString();
}
/// <summary>
/// 更新指示线位置
/// </summary>
private void UpdatePointers()
{
delayDistanceOffset = timePointerInterval * (negativePointerAmount - sizeNegative);
timePointerArea.sizeDelta = new Vector2(timePointerInterval * totalPointerAmount, 55f);
foreach (var pointer in timePointerList)
{
pointer.GetComponent<RectTransform>().anchoredPosition =
new Vector2((pointer.index + negativePointerAmount) * timePointerInterval + 15f - delayDistanceOffset, 0);
}
}
/// <summary>
/// 清楚所有指示线
/// </summary>
private void ClearPointers()
{
foreach (var pointer in timePointerList)
{
Destroy(pointer.gameObject);
}
timePointerList.Clear();
}
/// <summary>
/// 缩放时间线的展示时间宽度
/// </summary>
/// <param name="value">增减值</param>
public void ChangeSongTimeDistance(float value)
{
float oldDistance = songTimeDistance;
float changedDistance = songTimeDistance + value;
float songLength = songInformation.song.length;
if (changedDistance < 1 || changedDistance > songLength)
{
return;
}
float finalDistance = 0, finalValue = 0;
float superfluousDistance = changedDistance - songLength;
if (superfluousDistance > 0)
{
finalDistance = songLength;
finalValue = value - superfluousDistance;
}
else
{
finalDistance = changedDistance;
finalValue = value;
}
songTimeDistance = finalDistance;
float proportion = mainTimePointer.anchoredPosition.x /
visibleTimePointerArea.rect.width;
leftSideSongTime -= finalValue * (proportion);
rightSideSongTime += finalValue * (1 - proportion);
if (leftSideSongTime < -songInformation.delay)
{
rightSideSongTime += Mathf.Abs(leftSideSongTime);
leftSideSongTime = -songInformation.delay;
}
else if (rightSideSongTime > songLength)
{
leftSideSongTime -= (rightSideSongTime - songLength);
rightSideSongTime = songLength;
}
timePointerInterval = timePointerInterval / finalDistance * oldDistance;
UpdatePointers();
//UpdateListItems();
SetRange(leftSideSongTime);
}
}
}

View File

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

View File

@@ -0,0 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Ichni.Editor
{
public class Timeline : MonoBehaviour
{
public float songTime => EditorManager.instance.songInformation.songTime;
public float songBeat => EditorManager.instance.songInformation.songBeat;
public float beatmapStartTime => -EditorManager.instance.songInformation.delay;
public float timePerBeat => 60f / EditorManager.instance.songInformation.bpm;
public TimePointerModule timePointerModule;
public MusicPlayer musicPlayer;
}
}

View File

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

View File

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

View File

@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ToolBar : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

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

View File

@@ -9,7 +9,7 @@ namespace Ichni.RhythmGame
{
public override EffectState CheckEffectState()
{
float songTime = EditorManager.instance.songModule.songTime;
float songTime = EditorManager.instance.songInformation.songTime;
if (songTime < note.exactJudgeTime )
{

View File

@@ -9,7 +9,7 @@ namespace Ichni.RhythmGame
{
public override EffectState CheckEffectState()
{
float songTime = EditorManager.instance.songModule.songTime;
float songTime = EditorManager.instance.songInformation.songTime;
if (songTime < note.exactJudgeTime )
{

View File

@@ -12,7 +12,7 @@ namespace Ichni.RhythmGame
public override EffectState CheckEffectState()
{
float songTime = EditorManager.instance.songModule.songTime;
float songTime = EditorManager.instance.songInformation.songTime;
if (songTime < note.exactJudgeTime - generateTime)
{

View File

@@ -9,7 +9,7 @@ namespace Ichni.RhythmGame
{
public override EffectState CheckEffectState()
{
float songTime = EditorManager.instance.songModule.songTime;
float songTime = EditorManager.instance.songInformation.songTime;
if (songTime < note.exactJudgeTime )
{

View File

@@ -9,7 +9,7 @@ namespace Ichni.RhythmGame
{
public override EffectState CheckEffectState()
{
float songTime = EditorManager.instance.songModule.songTime;
float songTime = EditorManager.instance.songInformation.songTime;
if (songTime < note.exactJudgeTime )
{

View File

@@ -10,7 +10,7 @@ namespace Ichni.RhythmGame
{
public override EffectState CheckEffectState()
{
float songTime = EditorManager.instance.songModule.songTime;
float songTime = EditorManager.instance.songInformation.songTime;
if (songTime < note.exactJudgeTime )
{

View File

@@ -42,7 +42,7 @@ namespace Ichni.RhythmGame
/// </summary>
public virtual void UpdateNoteInStaticTrack()
{
float songTime = EditorManager.instance.songModule.songTime;
float songTime = EditorManager.instance.songInformation.songTime;
TrackTimeSubmoduleStatic trackTimeSubmoduleStatic = track.trackTimeSubmodule as TrackTimeSubmoduleStatic;
float startMove = exactJudgeTime - trackTimeSubmoduleStatic.trackTotalTime;
@@ -75,7 +75,7 @@ namespace Ichni.RhythmGame
}
}
float songTime = EditorManager.instance.songModule.songTime;
float songTime = EditorManager.instance.songInformation.songTime;
if (isJudged && songTime < exactJudgeTime)
{

View File

@@ -38,7 +38,7 @@ namespace Ichni.RhythmGame
private void Update()
{
if (timeDurationSubmodule.CheckTimeInDuration(EditorManager.instance.songModule.songTime))
if (timeDurationSubmodule.CheckTimeInDuration(EditorManager.instance.songInformation.songTime))
{
(trackTimeSubmodule as TrackTimeSubmoduleMovable)?.UpdateTrackPart();
}

View File

@@ -45,8 +45,8 @@ namespace Ichni.RhythmGame
{
if (trackPercent.animations.Count > 0)
{
trackSwitch.UpdateFlexibleInt(EditorManager.instance.songModule.songTime);
trackPercent.UpdateFlexibleFloat(EditorManager.instance.songModule.songTime);
trackSwitch.UpdateFlexibleInt(EditorManager.instance.songInformation.songTime);
trackPercent.UpdateFlexibleFloat(EditorManager.instance.songInformation.songTime);
SetPoint();
}
}

View File

@@ -38,7 +38,7 @@ namespace Ichni.RhythmGame
public void Update()
{
if (track.timeDurationSubmodule.CheckTimeInDuration(EditorManager.instance.songModule.songTime))
if (track.timeDurationSubmodule.CheckTimeInDuration(EditorManager.instance.songInformation.songTime))
{
trackPositioner.SetPercent(trackTimeSubmoduleMovable.headPercent);
}

View File

@@ -51,7 +51,7 @@ namespace Ichni.RhythmGame
{
if (trackPercent.animations.Count > 0)
{
trackPercent.UpdateFlexibleFloat(EditorManager.instance.songModule.songTime);
trackPercent.UpdateFlexibleFloat(EditorManager.instance.songInformation.songTime);
if (trackPercent.returnType == FlexibleReturnType.MiddleExecuting)
{
float finalValue = trackPercent.value;

View File

@@ -44,7 +44,7 @@ namespace Ichni.RhythmGame
public void UpdateTrackPart()
{
float songTime = EditorManager.instance.songModule.songTime;
float songTime = EditorManager.instance.songInformation.songTime;
headPercent = GetTrackPercent(songTime);
tailPercent = GetTrackPercent(songTime - visibleTrackTimeLength);

View File

@@ -46,6 +46,21 @@ namespace Ichni.RhythmGame
}
}
public partial class Trail
{
public static void SetAllTrails(bool emitting, bool willClear)
{
foreach (GameElement x in EditorManager.instance.beatmapContainer.gameElementList)
{
if (x is Trail t)
{
t.trailRenderer.emitting = emitting;
if(willClear) t.trailRenderer.Clear();
}
}
}
}
namespace Beatmap
{
public class Trail_BM : GameElement_BM