Files
Convention-Unity-Demo/Assets/Scripts/Framework/RootObject.cs

175 lines
6.1 KiB
C#
Raw Normal View History

2025-11-24 18:02:57 +08:00
using Convention;
using Convention.WindowsUI.Variant;
2025-09-25 19:04:05 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
2025-12-16 17:54:51 +08:00
using System.IO;
using System.Linq;
2025-09-25 19:04:05 +08:00
using UnityEngine;
using UnityEngine.InputSystem;
namespace Demo.Game
{
public class RootObject : ScriptableObject
{
2025-12-02 11:34:12 +08:00
protected override bool IsSelfEnableUpdate => false;
2025-12-02 14:25:04 +08:00
[Content] public Dictionary<Type, List<ScriptableObject>> UpdateChilds = new();
2025-09-25 19:04:05 +08:00
[Resources] public BasicAudioSystem audioSystem;
[Content] public GameController RootGameController;
2025-12-16 17:54:51 +08:00
[Setting]public string SourcePath;
[Header("GlobalConfig")]
public readonly HashSet<string> LoadedScriptSet = new();
public readonly Dictionary<int, ScriptableObject> LoadedScriptIndex = new();
public readonly Dictionary<ScriptableObject, int> LoadedScriptRIndex = new();
private int LoadedScriptCnt = 0;
/// <summary>
/// 被用于自动生成
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public int PushLoadedScriptObject(ScriptableObject obj)
{
while (LoadedScriptIndex.TryAdd(LoadedScriptCnt, obj) == false)
LoadedScriptCnt++;
LoadedScriptRIndex.Add(obj, LoadedScriptCnt);
return LoadedScriptCnt++;
}
/// <summary>
/// 被用于从缓存中生成
/// </summary>
/// <param name="obj"></param>
/// <param name="index"></param>
/// <returns></returns>
public int PushLoadedScriptObject(ScriptableObject obj, int index)
{
LoadedScriptIndex.Add(index, obj);
LoadedScriptRIndex.Add(obj, index);
return index;
}
/// <summary>
/// 通过序列号获得物体
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public ScriptableObject FindWithIndex(int index)
{
if(index<0)
return null;
return LoadedScriptIndex[index];
}
/// <summary>
/// 通过物体获得序列号
/// </summary>
/// <param name="obj"></param>
/// <returns>若无法找到将返回-1</returns>
public int FindIndex(ScriptableObject obj)
{
return LoadedScriptRIndex.TryGetValue(obj, out var index) ? index : -1;
}
2025-11-24 18:02:57 +08:00
protected override IEnumerator DoSomethingDuringApplyScript()
2025-09-25 19:04:05 +08:00
{
2025-11-24 18:02:57 +08:00
yield return base.DoSomethingDuringApplyScript();
ScriptUpdate(RootGameController.SongOffset, 0.01f, TickType.Reset);
if (RootGameController.IsMain)
2025-09-25 19:04:05 +08:00
{
2025-11-24 18:02:57 +08:00
Keyboard.current.onTextInput += InputCatchChar;
2025-09-25 19:04:05 +08:00
}
}
public override IEnumerator UnloadScript()
{
if (RootGameController.IsMain)
{
Keyboard.current.onTextInput -= InputCatchChar;
}
yield return base.UnloadScript();
2025-12-02 11:34:12 +08:00
UpdateChilds.Clear();
2025-09-25 19:04:05 +08:00
}
2025-11-24 18:02:57 +08:00
public void EnableScript(string sourcePath, GameController parent)
2025-09-25 19:04:05 +08:00
{
2025-10-08 00:35:50 +08:00
if (AllScriptableObjectCounterHierarchyItem == null)
{
AllScriptableObjectCounterHierarchyItem = HierarchyWindow.instance.CreateRootItemEntryWithBinders(typeof(ScriptableObject))[0];
}
2025-11-24 18:02:57 +08:00
SourcePath = sourcePath;
base.EnableScript(null);
2025-09-25 19:04:05 +08:00
RootGameController = parent;
}
[Serializable]
public struct InputCatchEntry
{
public float TimePoint;
public Vector2 Position;
public string InputKey;
}
/// <summary>
/// 这个捕获列表大多数时候只构造一次,等同与<see langword="readonly"/>
/// 但是会在<see cref="SubWorld"/>中被父关卡加载后会被赋值,这是唯一的例外,
/// 在多World项目中会由父世界的<see cref="SubWorld"/>传递给其他加载进来的<see cref="RootObject"/>
/// </summary>
public List<InputCatchEntry> InputCatch = new();
private void InputCatchChar(char ch)
{
if (RootGameController.IsAutoPlay)
return;
if (RootGameController.MainAudio.IsPlaying() == false)
return;
InputCatch.Add(new()
{
TimePoint = CurrentUpdateTickTimePoint,
InputKey = ch.ToString(),
Position = Mouse.current.position.ReadValue()
});
}
private float CurrentUpdateTickTimePoint;
protected override void UpdateTicks(float currentTime, float deltaTime, TickType tickType)
{
if (RootGameController.IsMain)
{
2025-12-02 14:25:04 +08:00
void foo()
2025-09-25 19:04:05 +08:00
{
2025-12-02 14:25:04 +08:00
if (RootGameController.IsAutoPlay)
return;
if (RootGameController.MainAudio.IsPlaying() == false)
return;
// 更新缓存时间
CurrentUpdateTickTimePoint = currentTime;
// 将距离当前更近的输入调整到更靠前的位置
InputCatch.Sort((x, y) => Mathf.Abs(x.TimePoint - currentTime).CompareTo(y.TimePoint - currentTime));
if (InputCatch.Count > 50)
InputCatch = InputCatch.GetRange(0, 50);
if (tickType == TickType.Start)
{
InputCatch.Clear();
}
2025-09-25 19:04:05 +08:00
}
2025-12-02 14:25:04 +08:00
foo();
2025-09-25 19:04:05 +08:00
}
2025-12-02 14:25:04 +08:00
foreach (var (type, items) in UpdateChilds)
2025-12-02 11:34:12 +08:00
{
2025-12-02 14:25:04 +08:00
using (Profiler.BeginZone($"{type.Name}.ScriptUpdate"))
foreach (var item in items)
{
try
{
item.ScriptUpdate(currentTime, deltaTime, tickType);
}
catch (Exception ex)
{
Debug.LogException(ex, item);
}
}
2025-12-02 11:34:12 +08:00
}
2025-09-25 19:04:05 +08:00
}
}
}