Signed-off-by: TRAfoer <lhf190@outlook.com>
This commit is contained in:
2025-10-02 14:01:23 +08:00
parent b29654e423
commit 529ab31282
21 changed files with 1081861 additions and 21597 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,7 @@ namespace Ichni.RhythmGame
{
public FlexibleFloat fieldOfView;
public GameCamera targetGameCamera;
public static CameraFieldOfView GenerateElement(string elementName, Guid id,
List<string> tags, bool isFirstGenerated, GameCamera gameCamera, FlexibleFloat fieldOfView)
{
@@ -21,13 +21,13 @@ namespace Ichni.RhythmGame
camFOV.animatedObject = gameCamera;
camFOV.targetGameCamera = gameCamera;
camFOV.fieldOfView = fieldOfView;
camFOV.animationReturnType = FlexibleReturnType.Before;
return camFOV;
}
public override void SetDefaultSubmodules()
{
timeDurationSubmodule = new TimeDurationSubmodule(this);
@@ -42,8 +42,29 @@ namespace Ichni.RhythmGame
targetGameCamera.perspectiveAngle = fieldOfView.value;
targetGameCamera.gameCamera.fieldOfView = fieldOfView.value;
}
else if (fieldOfView.isSwitchingReturnType)
{
animationReturnType = FlexibleReturnType.MiddleExecuting;
targetGameCamera.perspectiveAngle = fieldOfView.value;
targetGameCamera.gameCamera.fieldOfView = fieldOfView.value;
}
else
{
if (!EditorManager.instance.musicPlayer.isPlaying && animationReturnType != FlexibleReturnType.MiddleInterval)
{
targetGameCamera.perspectiveAngle = fieldOfView.value;
targetGameCamera.gameCamera.fieldOfView = fieldOfView.value;
animationReturnType = FlexibleReturnType.After;
}
else
{
targetGameCamera.perspectiveAngle = fieldOfView.value;
targetGameCamera.gameCamera.fieldOfView = fieldOfView.value;
animationReturnType = FlexibleReturnType.Before;
}
}
}
public override void ApplyTimeOffset(float offset)
{
base.ApplyTimeOffset(offset);
@@ -57,7 +78,7 @@ namespace Ichni.RhythmGame
{
matchedBM = new CameraFieldOfView_BM(elementName, elementGuid, tags, targetGameCamera.matchedBM as GameCamera_BM, fieldOfView.ConvertToBM());
}
public override void SetUpInspector()
{
base.SetUpInspector();
@@ -79,9 +100,9 @@ namespace Ichni.RhythmGame
public CameraFieldOfView_BM()
{
}
public CameraFieldOfView_BM(string elementName, Guid elementGuid, List<string> tags,
GameElement_BM attachedElement, FlexibleFloat_BM fieldOfView)
: base(elementName, elementGuid, tags, attachedElement)
@@ -91,10 +112,10 @@ namespace Ichni.RhythmGame
public override void ExecuteBM()
{
matchedElement = CameraFieldOfView.GenerateElement(elementName, elementGuid, tags, false,
GetElement(attachedElementGuid) as GameCamera, fieldOfView.ConvertToGameType());
matchedElement = CameraFieldOfView.GenerateElement(elementName, elementGuid, tags, false,
GetElement(attachedElementGuid) as GameCamera, fieldOfView.ConvertToGameType());
}
public override GameElement DuplicateBM(GameElement parent)
{
return CameraFieldOfView.GenerateElement(elementName, Guid.NewGuid(), tags, false,

View File

@@ -18,6 +18,13 @@ namespace Ichni.RhythmGame
public void SelectGameElement()
{
switch (elementToSelect)
{
case NoteBase note when EditorManager.instance.songInformation.songTime > note.exactJudgeTime:
return;
case PathNode pathNode1 when !pathNode1.isShowingSphere:
return;
}
EditorManager.instance.uiManager.hierarchy.FindTab(elementToSelect);
}

View File

@@ -361,6 +361,11 @@ namespace Ichni.RhythmGame
List<BaseElement_BM> result = new List<BaseElement_BM>();
foreach (BaseElement_BM element in clip)
{
if (element == null)
{
continue;
}
if (element.attachedElementGuid == elementGuid)
{
result.Add(element);

View File

@@ -5,6 +5,7 @@ using System.Linq;
using Dreamteck.Splines;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UniRx;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.InputSystem;
@@ -41,6 +42,13 @@ namespace Ichni.RhythmGame
hold.trackPositioner.updateMethod = SplineUser.UpdateMethod.LateUpdate;
hold.isOnTrack = true;
hold.UpdateNoteInTrack();
Observable.NextFrame().Subscribe(_ =>
{
hold.UpdateNoteInTrack();
track.Refresh();
track.trackPathSubmodule?.path.RebuildImmediate();
});
}
else
{
@@ -59,6 +67,7 @@ namespace Ichni.RhythmGame
}
return hold;
}
}

View File

@@ -67,7 +67,7 @@ namespace Ichni.RhythmGame
public override void Refresh()
{
base.Refresh();
if (noteVisual != null)
{
noteVisual.Refresh();
@@ -91,11 +91,13 @@ namespace Ichni.RhythmGame
if (isFirstJudged && songTime < exactJudgeTime)
{
isFirstJudged = false;
noteVisual.GetComponent<Collider>().enabled = !isFirstJudged;
}
else if (!isFirstJudged && songTime >= exactJudgeTime)
{
noteAudioSubmodule?.PlayNoteJudgeAudios(editor.currentJudgeType);
isFirstJudged = true;
noteVisual.GetComponent<Collider>().enabled = !isFirstJudged;
}
// 判定单元更新
@@ -140,7 +142,7 @@ namespace Ichni.RhythmGame
}
// 碰撞体状态
noteVisual.GetComponent<Collider>().enabled = !isFirstJudged;
}
}

View File

@@ -344,32 +344,32 @@ namespace Ichni.Editor
if (allResults.Count > 0)
{
// 完整排序
allResults.Sort((a, b) =>
{
// 先按sorting layer
int layerCompare = SortingLayer.GetLayerValueFromID(b.sortingLayer)
.CompareTo(SortingLayer.GetLayerValueFromID(a.sortingLayer));
if (layerCompare != 0) return layerCompare;
// allResults.Sort((a, b) =>
// {
// // 先按sorting layer
// int layerCompare = SortingLayer.GetLayerValueFromID(b.sortingLayer)
// .CompareTo(SortingLayer.GetLayerValueFromID(a.sortingLayer));
// if (layerCompare != 0) return layerCompare;
// 再按sorting order
int orderCompare = b.sortingOrder.CompareTo(a.sortingOrder);
if (orderCompare != 0) return orderCompare;
// // 再按sorting order
// int orderCompare = b.sortingOrder.CompareTo(a.sortingOrder);
// if (orderCompare != 0) return orderCompare;
// 最后按depth
return b.depth.CompareTo(a.depth);
});
// // 最后按depth
// return b.depth.CompareTo(a.depth);
// });
hoveredUI = allResults[0].gameObject;
string text = $"UI: {hoveredUI.name}, Layer: {SortingLayer.IDToName(allResults[0].sortingLayer)}, Order: {allResults[0].sortingOrder}";
if (UIText.text != text)
{
UIText.text = text;
}
// hoveredUI = allResults[0].gameObject;
// string text = $"UI: {hoveredUI.name}, Layer: {SortingLayer.IDToName(allResults[0].sortingLayer)}, Order: {allResults[0].sortingOrder}";
// if (UIText.text != text)
// {
// UIText.text = text;
// }
return true;
}
UIText.text = "No UI";
//UIText.text = "No UI";
return false;
}
}

View File

@@ -285,7 +285,8 @@ namespace Ichni
e.submoduleList.ForEach(s =>
{
s.SaveBM();
clip.Add(s.matchedBM);
if (s.matchedBM != null)
clip.Add(s.matchedBM);
});
});
@@ -295,41 +296,84 @@ namespace Ichni
private void _LoadClip(GameElement target, string clipName)
{
string filePath = Application.streamingAssetsPath + "/Clips/" + clipName + ".json";
List<BaseElement_BM> clip = ES3.Load<List<BaseElement_BM>>("Clip", filePath, ProjectManager.SaveSettings);
//对于第一个元素,需要特殊处理,将它放入目标物体的子物体列表中
GameElement_BM first = clip[0] as GameElement_BM;
List<BaseElement_BM> firstAttaches = GameElement_BM.GetAllAttachedBaseElements(first, clip);
first.elementGuid = Guid.NewGuid();
GameElement_BM.identifier.TryAdd(first.elementGuid, first);
firstAttaches.ForEach(e => { e.attachedElementGuid = first.elementGuid; });
//将目标物体临时存入读存档的Dictionary中
target.SaveBM();
GameElement_BM.identifier.TryAdd(target.elementGuid, target.matchedBM as GameElement_BM);
(target.matchedBM as GameElement_BM).matchedElement = target;
first.attachedElementGuid = target.elementGuid;
for (var index = 1; index < clip.Count; index++)
try
{
var element = clip[index];
if (element is GameElement_BM gameElement)
string filePath = Application.streamingAssetsPath + "/Clips/" + clipName + ".json";
List<BaseElement_BM> clip = ES3.Load<List<BaseElement_BM>>("Clip", filePath, ProjectManager.SaveSettings);
if (clip == null || clip.Count == 0)
{
List<BaseElement_BM> attachedElements = GameElement_BM.GetAllAttachedBaseElements(gameElement, clip);
gameElement.elementGuid = Guid.NewGuid();
GameElement_BM.identifier.TryAdd(gameElement.elementGuid, gameElement);
attachedElements.ForEach(e => { e.attachedElementGuid = gameElement.elementGuid; });
Debug.LogError("Clip is empty or null");
return;
}
// 验证第一个元素
if (!(clip[0] is GameElement_BM first))
{
Debug.LogError("First element is not a GameElement_BM");
return;
}
// 处理目标对象 - 添加清理机制
target.SaveBM();
bool targetAdded = GameElement_BM.identifier.TryAdd(target.elementGuid, target.matchedBM as GameElement_BM);
if (!targetAdded)
{
Debug.LogWarning("Target element already exists in identifier dictionary");
}
// 处理第一个元素及其附加元素
ProcessGameElement(first, clip, target.elementGuid);
// 处理后续元素
for (var index = 1; index < clip.Count; index++)
{
if (clip[index] is GameElement_BM gameElement)
{
ProcessGameElement(gameElement, clip, null);
}
else
{
// 非GameElement_BM直接执行
clip[index].ExecuteBM();
}
}
}
first.ExecuteBM();
for (var index = 1; index < clip.Count; index++)
catch (Exception ex)
{
clip[index].ExecuteBM();
Debug.LogError($"Failed to load clip: {ex.Message}");
}
}
private void ProcessGameElement(GameElement_BM gameElement, List<BaseElement_BM> clip, Guid? attachToGuid)
{
List<BaseElement_BM> attachedElements = GameElement_BM.GetAllAttachedBaseElements(gameElement, clip);
// 生成新GUID并验证
gameElement.elementGuid = Guid.NewGuid();
bool elementAdded = GameElement_BM.identifier.TryAdd(gameElement.elementGuid, gameElement);
if (!elementAdded)
{
Debug.LogError($"Failed to add element with GUID: {gameElement.elementGuid}");
return;
}
// 更新附加元素
attachedElements.ForEach(e =>
{
e.attachedElementGuid = gameElement.elementGuid;
});
// 如果需要附加到其他元素
if (attachToGuid.HasValue)
{
gameElement.attachedElementGuid = attachToGuid.Value;
}
gameElement.ExecuteBM();
}
}
public class BeatmapMergeManager

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 72a537e19a9032a41bb95ae02311c661
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4f5c7be7553de29479b3e234c8b11417
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c9aa8aaf39c47324a9ec3ed7a8365d09
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 48117c741d5266849bafe0735278224d
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 264af7ffb6d4d8145b9da61df2f7e0bf
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
"songName" : "alunite cas.wav",
"bpm" : 200,
"delay" : 0,
"offset" : 0,
"offset" : -0.05,
"attachedElementGuid" : {
"value" : "00000000-0000-0000-0000-000000000000"
}