using Convention; using Convention.WindowsUI.Variant; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; namespace Demo.Game { public class RootObject : ScriptableObject { [Resources] public BasicAudioSystem audioSystem; [Content] public GameController RootGameController; public string SourcePath; protected override IEnumerator DoSomethingDuringApplyScript() { yield return base.DoSomethingDuringApplyScript(); ScriptUpdate(RootGameController.SongOffset, 0.01f, TickType.Reset); if (RootGameController.IsMain) { Keyboard.current.onTextInput += InputCatchChar; } } public override IEnumerator UnloadScript() { if (RootGameController.IsMain) { Keyboard.current.onTextInput -= InputCatchChar; } yield return base.UnloadScript(); } public void EnableScript(string sourcePath, GameController parent) { AllScriptableObjectCounter = 0; if (AllScriptableObjectCounterHierarchyItem == null) { AllScriptableObjectCounterHierarchyItem = HierarchyWindow.instance.CreateRootItemEntryWithBinders(typeof(ScriptableObject))[0]; } SourcePath = sourcePath; base.EnableScript(null); RootGameController = parent; } [Serializable] public struct InputCatchEntry { public float TimePoint; public Vector2 Position; public string InputKey; } /// /// 这个捕获列表大多数时候只构造一次,等同与, /// 但是会在中被父关卡加载后会被赋值,这是唯一的例外, /// 在多World项目中会由父世界的传递给其他加载进来的 /// public List 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) { void Foo() { 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(); } } Foo(); } base.UpdateTicks(currentTime, deltaTime, tickType); } } }