修复了一些bug(包含窗口预制体中的错误与{}列表解析存在死循环的错误)
This commit is contained in:
@@ -78,9 +78,11 @@ namespace Demo.Editor
|
||||
|
||||
[Content, SerializeField] private List<BPMLine> BPMLineEntries = new();
|
||||
[Content] public int BPMFraction = 4;
|
||||
[Content] public float BPMOffset = 0;
|
||||
[Content] public float SongOffset = 0;
|
||||
[Content] public float BPM = 60;
|
||||
|
||||
private float onebarDeltaTime;
|
||||
|
||||
private void InjectSetSongCurrentTime(float time)
|
||||
{
|
||||
// 秒,可见长度,以下相同,注意并非百分比
|
||||
@@ -170,8 +172,9 @@ namespace Demo.Editor
|
||||
|
||||
// BPM
|
||||
BPM = (float)MainGameController.MainConfig.FindItem(nameof(BPM), BPM);
|
||||
onebarDeltaTime = 60.0f / (BPM * BPMFraction);
|
||||
BPMFraction = (int)MainGameController.MainConfig.FindItem(nameof(BPMFraction), BPMFraction);
|
||||
BPMOffset = (float)MainGameController.MainConfig.FindItem(nameof(BPMOffset), BPMOffset);
|
||||
SongOffset = (float)MainGameController.MainConfig.FindItem(nameof(SongOffset), SongOffset);
|
||||
|
||||
// 绘制时频
|
||||
var texturePath = (string)MainGameController.MainConfig.FindItem(nameof(SpectrumRenderTexture), null);
|
||||
@@ -492,7 +495,6 @@ namespace Demo.Editor
|
||||
|
||||
var time = MainGameController.CurrentTime;
|
||||
|
||||
float onebarDeltaTime = 60.0f / (BPM * BPMFraction);
|
||||
int BPMLineEntriesIndex = 0;
|
||||
float farAplha = (1 - SpectrumSeeline.currentPercent) * 0.5f + 0.5f;
|
||||
float foucs = Mathf.CeilToInt((time + leftClipFrom ) / onebarDeltaTime) * onebarDeltaTime;
|
||||
|
||||
@@ -33,12 +33,12 @@ namespace Demo.Editor
|
||||
{
|
||||
if (name == nameof(ScriptableObject.LoadSubScript))
|
||||
{
|
||||
stream.WriteLine("#define __build_in_pragma #");
|
||||
stream.WriteLine("#define __build_in_to_text(x) #x");
|
||||
// stream.WriteLine("#define __build_in_pragma #");
|
||||
// stream.WriteLine("#define __build_in_to_text(x) #x");
|
||||
|
||||
stream.Write("/*\n" + description + "\n*/\n");
|
||||
stream.Write($"#define {name}({string.Join(',', paramList)}) __build_in_pragma include __build_in_to_text(./##{paramList.First()})\n\n");
|
||||
//stream.Write($"#define {name}({string.Join(',', paramList)})\n\n");
|
||||
// stream.Write("/*\n" + description + "\n*/\n");
|
||||
// stream.Write($"#define {name}({string.Join(',', paramList)}) __build_in_pragma include __build_in_to_text(./##{paramList.First()})\n\n");
|
||||
stream.Write($"#define {name}({string.Join(',', paramList)})\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -39,8 +39,8 @@ namespace Demo.Game
|
||||
public string WhichOpenProject { get; private set; } = null;
|
||||
public ProjectDefaultFileStyle CurrentProjectDefaultFileStyle = default;
|
||||
|
||||
public float SongOffset;
|
||||
public float CurrentTime => MainAudio.CurrentTime - SongOffset;
|
||||
public float SongOffset = 0;
|
||||
public float CurrentTime = 0;
|
||||
|
||||
public Transform MainCameraTransform => MainCamera.transform;
|
||||
|
||||
@@ -122,10 +122,10 @@ namespace Demo.Game
|
||||
{
|
||||
ScriptableObject.FastScriptableObjectTypen = content.ScriptableObjectTypen;
|
||||
ScriptableObject.IsAutoPlay = content.IsAutoPlay;
|
||||
ScriptableObject.OneBarTime = (float)MainConfig.FindItem(nameof(Editor.EditorController.BPM), Editor.EditorController.instance.BPM);
|
||||
ScriptableObject.OneBarTime = 60.0f / (float)MainConfig.FindItem(nameof(Editor.EditorController.BPM), Editor.EditorController.instance.BPM);
|
||||
SongOffset = (float)MainConfig.FindItem(nameof(SongOffset), SongOffset);
|
||||
SetupSongDuration = GameContent.instance.SetupSongDuration;
|
||||
SetSongCurrentTime = GameContent.instance.SetSongCurrentTime;
|
||||
SongOffset = GameContent.instance.SongOffset;
|
||||
// Open Project
|
||||
WhichOpenProject = (string)MainConfig.FindItem(nameof(WhichOpenProject), WhichOpenProject);
|
||||
if (string.IsNullOrEmpty(WhichOpenProject) == false)
|
||||
@@ -159,7 +159,7 @@ namespace Demo.Game
|
||||
string defaultRootPath = "root" + CurrentProjectDefaultFileStyle switch
|
||||
{
|
||||
ProjectDefaultFileStyle.PY => ".py",
|
||||
_ => ".h"
|
||||
_ => ".cpp"
|
||||
};
|
||||
if (content.IsCreateNewProject)
|
||||
{
|
||||
@@ -207,7 +207,7 @@ namespace Demo.Game
|
||||
yield return null;
|
||||
IsEnableUpdate = true;
|
||||
yield return new WaitUntil(() => MainObject != null);
|
||||
MainObject.ScriptUpdate(0, Time.deltaTime, ScriptableObject.TickType.Reset);
|
||||
MainObject.ScriptUpdate(SongOffset, Time.deltaTime, ScriptableObject.TickType.Reset);
|
||||
}
|
||||
|
||||
|
||||
@@ -216,9 +216,9 @@ namespace Demo.Game
|
||||
MainAudio.Stop();
|
||||
if (IsMain)
|
||||
{
|
||||
SetSongCurrentTime(-SongOffset);
|
||||
SetSongCurrentTime(SongOffset);
|
||||
}
|
||||
MainObject.ScriptUpdate(-SongOffset, Time.deltaTime, ScriptableObject.TickType.Reset);
|
||||
MainObject.ScriptUpdate(SongOffset, Time.deltaTime, ScriptableObject.TickType.Reset);
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
@@ -255,6 +255,7 @@ namespace Demo.Game
|
||||
|
||||
private void Update()
|
||||
{
|
||||
CurrentTime = MainAudio.CurrentTime + SongOffset;
|
||||
float deltaTime = Time.deltaTime;
|
||||
var currentClip = MainAudio.CurrentClip;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Demo.Game
|
||||
}
|
||||
finally
|
||||
{
|
||||
ScriptUpdate(0, 0.01f, TickType.Start);
|
||||
ScriptUpdate(RootGameController.SongOffset, 0.01f, TickType.Start);
|
||||
if (RootGameController.IsMain)
|
||||
{
|
||||
Keyboard.current.onTextInput += InputCatchChar;
|
||||
|
||||
@@ -35,8 +35,7 @@ namespace Demo
|
||||
public static (string functionName, string[] arguments) ParseFunctionCall(string input)
|
||||
{
|
||||
// 匹配函数名和参数部分
|
||||
string pattern = @"^(\w+)\s*\(\s*(.*?)\s*\)\s*;?$";
|
||||
Match match = Regex.Match(input, pattern);
|
||||
Match match = Regex.Match(input, @"^(\w+)\s*\(\s*(.*?)\s*\)\s*;?$");
|
||||
|
||||
if (!match.Success)
|
||||
return (null, new string[0]);
|
||||
@@ -56,14 +55,84 @@ namespace Demo
|
||||
if (string.IsNullOrWhiteSpace(argumentsString))
|
||||
return new string[0];
|
||||
|
||||
// 处理字符串字面量和普通参数的正则表达式
|
||||
string argPattern = @"""(?:[^""\\]|\\.)*""|[^,]+";
|
||||
var arguments = new List<string>();
|
||||
int i = 0;
|
||||
|
||||
while (i < argumentsString.Length)
|
||||
{
|
||||
// 跳过空白字符
|
||||
while (i < argumentsString.Length && char.IsWhiteSpace(argumentsString[i]))
|
||||
i++;
|
||||
|
||||
// 越界检查
|
||||
if (i >= argumentsString.Length)
|
||||
break;
|
||||
|
||||
string argument = ExtractArgument(argumentsString, ref i);
|
||||
if (!string.IsNullOrEmpty(argument))
|
||||
arguments.Add(argument.Trim());
|
||||
|
||||
return Regex.Matches(argumentsString, argPattern)
|
||||
.Cast<Match>()
|
||||
.Select(m => m.Value.Trim())
|
||||
.Where(arg => !string.IsNullOrEmpty(arg))
|
||||
.ToArray();
|
||||
// 跳过空白字符
|
||||
while (i < argumentsString.Length && char.IsWhiteSpace(argumentsString[i]))
|
||||
i++;
|
||||
|
||||
// 越界检查
|
||||
if (i >= argumentsString.Length)
|
||||
break;
|
||||
|
||||
// 必定是逗号, 否则异常情况
|
||||
if (argumentsString[i] != ',')
|
||||
throw new InvalidOperationException("Parser is invalid logic");
|
||||
i++;
|
||||
}
|
||||
|
||||
return arguments.ToArray();
|
||||
}
|
||||
|
||||
// 提取单个参数的方法,支持花括号和字符串字面量
|
||||
private static string ExtractArgument(string input, ref int index)
|
||||
{
|
||||
int start = index;
|
||||
|
||||
if (input[index] == '"')
|
||||
{
|
||||
// 处理字符串字面量
|
||||
index++; // 跳过开始的引号
|
||||
while (index < input.Length)
|
||||
{
|
||||
if (input[index] == '"' && (index == 0 || input[index - 1] != '\\'))
|
||||
{
|
||||
index++; // 跳过结束的引号
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
else if (input[index] == '{')
|
||||
{
|
||||
// 处理花括号内的内容
|
||||
int braceCount = 0;
|
||||
while (index < input.Length)
|
||||
{
|
||||
if (input[index] == '{')
|
||||
braceCount++;
|
||||
else if (input[index] == '}')
|
||||
braceCount--;
|
||||
|
||||
index++;
|
||||
|
||||
if (braceCount == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 处理普通参数(直到遇到逗号)
|
||||
while (index < input.Length && input[index] != ',')
|
||||
index++;
|
||||
}
|
||||
|
||||
return input[start..index];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,6 +465,28 @@ namespace Demo
|
||||
}
|
||||
}
|
||||
|
||||
public partial class ScriptableObject
|
||||
{
|
||||
[Content] public int UpdatePerFrame = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 指定多少个<see cref="TickType.Update"/>状态的<see cref="UpdateTicks(float, float, TickType)"/>执行一次更新,不会影响到子物体
|
||||
/// 属于性能优化的高级选项
|
||||
/// </summary>
|
||||
/// <param name="frame">间隔帧数, 小于等于1的值代表无论如何都会更新</param>
|
||||
[ScriptableCall(@"
|
||||
<summary>
|
||||
指定多少个Update状态的UpdateTicks执行一次更新,不会影响到子物体
|
||||
属于性能优化的高级选项
|
||||
</summary>
|
||||
<param name=""frame"">间隔帧数, 小于等于1的值代表无论如何都会更新</param>
|
||||
")]
|
||||
public void SetUpdatePerFrame(string frame)
|
||||
{
|
||||
UpdatePerFrame = Mathf.Max(1, int.Parse(frame));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>使用<see cref="ScriptableCallAttribute"/>标记可编辑脚本所能够调用的函数,并附加注释</para>
|
||||
/// <para>使用<see cref="DefaultScriptAttribute"/>标记派生类,并附加默认模板</para>
|
||||
@@ -800,6 +891,7 @@ namespace Demo
|
||||
//LateUpdate
|
||||
}
|
||||
|
||||
[Content, SerializeField] private int ScriptUpdateCounter = 0;
|
||||
public void ScriptUpdate(float currentTime, float deltaTime, TickType tickType)
|
||||
{
|
||||
if (IsEnableUpdate == false)
|
||||
@@ -809,7 +901,13 @@ namespace Demo
|
||||
#if UNITY_EDITOR
|
||||
s_PreparePerfMarker.Begin(this);
|
||||
#endif
|
||||
UpdateTicks(currentTime, deltaTime, tickType);
|
||||
// UpdateTicks
|
||||
{
|
||||
if (ScriptUpdateCounter % UpdatePerFrame == 0)
|
||||
UpdateTicks(currentTime, deltaTime, tickType);
|
||||
ScriptUpdateCounter += tickType == TickType.Update ? 1 : 0;
|
||||
}
|
||||
// Childs UpdateTicks
|
||||
foreach (var child in Childs)
|
||||
{
|
||||
child.ScriptUpdate(currentTime, deltaTime, tickType);
|
||||
|
||||
@@ -224,10 +224,12 @@ namespace Demo.Game
|
||||
|
||||
public static Dictionary<string, Func<ScriptableObject>> GetScriptableObjectInstantiate()
|
||||
{
|
||||
return new Dictionary<string, Func<ScriptableObject>>(GameObjectInstantiate.Union(TickUpdatementInstantiate)
|
||||
.Union(MaterialUpdatementInstantiate)
|
||||
.Union(SplineInstantiate)
|
||||
.Union(JudgementInstantiate));
|
||||
return new Dictionary<string, Func<ScriptableObject>>(GameObjectInstantiate
|
||||
.Union(DDTInstantiate)
|
||||
.Union(TickUpdatementInstantiate)
|
||||
.Union(MaterialUpdatementInstantiate)
|
||||
.Union(SplineInstantiate)
|
||||
.Union(JudgementInstantiate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user