diff --git a/Assets/Scripts/Actions/ActionHelper.cs b/Assets/Scripts/Actions/ActionHelper.cs index d1c4eed4..606f2fcc 100644 --- a/Assets/Scripts/Actions/ActionHelper.cs +++ b/Assets/Scripts/Actions/ActionHelper.cs @@ -278,6 +278,11 @@ public class ActionHelper var dictAction = (XMLTool.DictionaryAction)act; return QFramework.OperationChangeAction.Allocate(dictAction.args); } + case "ShowScore": + { + var dictAction = (XMLTool.DictionaryAction)act; + return QFramework.ShowScoreAction.Allocate(dictAction.args); + } default: Debug.LogError($"没有找到此Action的类型{act.Type}"); break; diff --git a/Assets/Scripts/Actions/ShowScoreAction.cs b/Assets/Scripts/Actions/ShowScoreAction.cs new file mode 100644 index 00000000..e3edf2f1 --- /dev/null +++ b/Assets/Scripts/Actions/ShowScoreAction.cs @@ -0,0 +1,82 @@ +using QFramework.Example; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace QFramework +{ + internal class ShowScoreAction : IAction + { + + public System.Action OnFinished { get; set; } + + + private ShowScoreAction() + { + } + + private static readonly SimpleObjectPool mPool = + new SimpleObjectPool(() => new ShowScoreAction(), null, 10); + + Dictionary datas; + public static ShowScoreAction Allocate(Dictionary datas, System.Action OnFinished = null) + { + var retNode = mPool.Allocate(); + retNode.ActionID = ActionKit.ID_GENERATOR++; + retNode.Deinited = false; + retNode.Reset(); + retNode.datas = datas; + retNode.OnFinished = OnFinished; + return retNode; + } + + + public ulong ActionID { get; set; } + public ActionStatus Status { get; set; } + + public void OnStart() + { + UIScoreData data = new UIScoreData(); + if (datas.ContainsKey("onlyCurModule")) + { + if (bool.TryParse(datas["onlyCurModule"], out data.onlyCurModule) == false) + { + data.onlyCurModule = false; + } + } + UIKit.OpenPanelAsync(canvasLevel: UILevel.PopUI, uiData: data).ToAction().StartGlobal(() => this.Finish()); + } + + public void OnExecute(float dt) + { + //this.Finish(); + //OnFinished?.Invoke(); + } + + public void OnFinish() + { + } + + public void Reset() + { + Status = ActionStatus.NotStart; + Paused = false; + } + + public bool Paused { get; set; } + + public void Deinit() + { + if (!Deinited) + { + OnFinished = null; + Deinited = true; + mPool.Recycle(this); + } + } + + public bool Deinited { get; set; } + } + + +} \ No newline at end of file diff --git a/Assets/Scripts/Actions/ShowScoreAction.cs.meta b/Assets/Scripts/Actions/ShowScoreAction.cs.meta new file mode 100644 index 00000000..c2877c41 --- /dev/null +++ b/Assets/Scripts/Actions/ShowScoreAction.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0ba81906fe012d2468c5a69a833ed765 +timeCreated: 1647655796 \ No newline at end of file diff --git a/Assets/Scripts/Editor/LowercaseFileRenamer.cs b/Assets/Scripts/Editor/LowercaseFileRenamer.cs new file mode 100644 index 00000000..2333e5a6 --- /dev/null +++ b/Assets/Scripts/Editor/LowercaseFileRenamer.cs @@ -0,0 +1,145 @@ +#if UNITY_EDITOR +using UnityEditor; +using UnityEngine; +using System.IO; +using System; + +public class WindowsLowercaseRenamer : EditorWindow +{ + [MenuItem("Assets/Windows安全重命名")] + private static void SafeRenameAll() + { + string dataPath = Global.dataPath; + + // 新增:处理根目录名称 + ProcessRootDirectory(dataPath); + + // 处理子目录和文件 + ProcessDirectoriesRecursive(dataPath); + ProcessFilesRecursive(dataPath); + + AssetDatabase.Refresh(); + Debug.Log("安全重命名完成!"); + } + // 新增方法:处理根目录 + private static void ProcessRootDirectory(string originalPath) + { + try + { + DirectoryInfo rootInfo = new DirectoryInfo(originalPath); + string targetRootName = rootInfo.Name.ToLowerInvariant(); + + // 如果根目录名称不符合规范 + if (rootInfo.Name != targetRootName) + { + string parentPath = rootInfo.Parent.FullName; + string newRootPath = Path.Combine(parentPath, targetRootName); + + // 特殊处理:根目录重命名需要额外权限 + if (Directory.Exists(newRootPath)) + { + string tempPath = Path.Combine(parentPath, Guid.NewGuid().ToString()); + Directory.Move(originalPath, tempPath); + Directory.Move(tempPath, newRootPath); + } + else + { + Directory.Move(originalPath, newRootPath); + } + + Debug.Log($"根目录重命名成功: {originalPath} → {newRootPath}"); + + // 更新全局路径(如果需要) + Global.dataPath = newRootPath; // 根据实际Global类的实现可能需要调整 + } + } + catch (Exception ex) + { + Debug.LogError($"根目录重命名失败: {ex.Message}"); + } + } + private static void ProcessDirectoriesRecursive(string path) + { + foreach (var dirPath in Directory.GetDirectories(path)) + { + // 递归处理子目录 + ProcessDirectoriesRecursive(dirPath); + + DirectoryInfo dirInfo = new DirectoryInfo(dirPath); + string targetName = dirInfo.Name.ToLowerInvariant(); + + // 仅当实际目录名不符合规范时才重命名 + if (dirInfo.Name != targetName) + { + string parentPath = dirInfo.Parent.FullName; + string newPath = Path.Combine(parentPath, targetName); + + try + { + // 特殊处理:Windows需要先重命名到临时名称 + //if (Directory.Exists(newPath)) + //{ + // string tempPath = Path.Combine(parentPath, Guid.NewGuid().ToString()); + // Directory.Move(dirPath, tempPath); + // Directory.Move(tempPath, newPath); + //} + //else + //{ + Directory.Move(dirPath, newPath); + //} + + Debug.Log($"目录重命名成功: {dirPath} → {newPath}"); + } + catch (Exception ex) + { + Debug.LogError($"目录重命名失败: {dirPath}\n{ex.Message}"); + } + } + } + } + + private static void ProcessFilesRecursive(string path) + { + foreach (var filePath in Directory.GetFiles(path)) + { + FileInfo fileInfo = new FileInfo(filePath); + string targetName = Path.GetFileNameWithoutExtension(fileInfo.Name).ToLowerInvariant(); + string targetExt = fileInfo.Extension.ToLowerInvariant(); + string newFileName = $"{targetName}{targetExt}"; + + // 比较实际文件名 + if (fileInfo.Name != newFileName) + { + string newPath = Path.Combine(fileInfo.DirectoryName, newFileName); + + try + { + // Windows特殊处理:如果目标存在但大小写不同 + if (File.Exists(newPath)) + { + string tempPath = Path.Combine(fileInfo.DirectoryName, Guid.NewGuid().ToString() + fileInfo.Extension); + File.Move(filePath, tempPath); + File.Move(tempPath, newPath); + } + else + { + File.Move(filePath, newPath); + } + + Debug.Log($"文件重命名成功: {filePath} → {newPath}"); + } + catch (Exception ex) + { + Debug.LogError($"文件重命名失败: {filePath}\n{ex.Message}"); + } + } + } + + // 递归子目录 + foreach (var dirPath in Directory.GetDirectories(path)) + { + ProcessFilesRecursive(dirPath); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Scripts/Editor/LowercaseFileRenamer.cs.meta b/Assets/Scripts/Editor/LowercaseFileRenamer.cs.meta new file mode 100644 index 00000000..852097e7 --- /dev/null +++ b/Assets/Scripts/Editor/LowercaseFileRenamer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3fc1a350612ff074eb9880438ed8d526 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Editor/VirtualFPostProcess.cs b/Assets/Scripts/Editor/VirtualFPostProcess.cs index a89bdefc..41b0b061 100644 --- a/Assets/Scripts/Editor/VirtualFPostProcess.cs +++ b/Assets/Scripts/Editor/VirtualFPostProcess.cs @@ -7,60 +7,72 @@ using UnityEngine; public class VirtualFPostProcess : IPostprocessBuildWithReport { - // 定义回调优先级(越低越先执行) public int callbackOrder => 0; - // 在打包完成后执行 public void OnPostprocessBuild(BuildReport report) { - // 获取项目根目录路径 string projectPath = Application.dataPath; - - // 获取Data文件夹的路径 string dataFolderPath = Path.Combine(projectPath, "../Data"); + string buildOutputPath = GetValidBuildPath(report); - // 获取打包后的输出目录 - string buildOutputPath = report.summary.outputPath; - if (buildOutputPath.Contains(".exe")) - { - var paths = buildOutputPath.Split('/'); - buildOutputPath = buildOutputPath.Replace(paths[paths.Length - 1], ""); - } - // 检查Data文件夹是否存在 if (Directory.Exists(dataFolderPath)) { - // 将Data文件夹复制到打包后的目标目录 - string targetDataPath = Path.Combine(buildOutputPath, "Data"); - CopyDirectory(dataFolderPath, targetDataPath); - Debug.Log($"Data folder copied to build output directory: {targetDataPath}"); + // 目标目录强制小写 + string targetDataPath = Path.Combine(buildOutputPath, "data"); + CopyDirectoryWithLowerCaseNames(dataFolderPath, targetDataPath); + Debug.Log($"数据目录已复制到: {targetDataPath}"); } else { - Debug.LogWarning("Data folder not found at: " + dataFolderPath); + Debug.LogWarning("未找到数据目录: " + dataFolderPath); } } - // 递归复制文件夹的辅助方法,覆盖已有文件和文件夹 - private void CopyDirectory(string sourceDir, string destinationDir) + private string GetValidBuildPath(BuildReport report) { - // 确保目标目录存在 - if (!Directory.Exists(destinationDir)) + string path = report.summary.outputPath; + if (path.Contains(".exe")) { - Directory.CreateDirectory(destinationDir); + return Path.GetDirectoryName(path); + } + return path; + } + + private void CopyDirectoryWithLowerCaseNames(string sourceDir, string targetDir) + { + // 创建小写目标目录 + var lowerTargetDir = ConvertToLowerPath(targetDir); + Directory.CreateDirectory(lowerTargetDir); + + // 复制文件(带小写转换) + foreach (var file in Directory.GetFiles(sourceDir)) + { + string fileName = Path.GetFileName(file); + string lowerName = ConvertToLowerPath(fileName); + File.Copy(file, Path.Combine(lowerTargetDir, lowerName), true); } - // 遍历源目录中的文件 - foreach (string file in Directory.GetFiles(sourceDir)) + // 递归处理子目录(带小写转换) + foreach (var dir in Directory.GetDirectories(sourceDir)) { - string destFile = Path.Combine(destinationDir, Path.GetFileName(file)); - File.Copy(file, destFile, true); // 覆盖已有文件 - } - - // 遍历源目录中的子文件夹 - foreach (string subDir in Directory.GetDirectories(sourceDir)) - { - string destSubDir = Path.Combine(destinationDir, Path.GetFileName(subDir)); - CopyDirectory(subDir, destSubDir); // 递归复制子文件夹 + string dirName = Path.GetFileName(dir); + string lowerDirName = ConvertToLowerPath(dirName); + CopyDirectoryWithLowerCaseNames(dir, Path.Combine(lowerTargetDir, lowerDirName)); } } -} + + // 中英文混合路径转小写 + private string ConvertToLowerPath(string input) + { + char[] chars = input.ToCharArray(); + for (int i = 0; i < chars.Length; i++) + { + // 只处理ASCII字母字符(中文等Unicode字符保持不变) + if (chars[i] >= 'A' && chars[i] <= 'Z') + { + chars[i] = (char)(chars[i] | 0x20); // 快速转小写 + } + } + return new string(chars); + } +} \ No newline at end of file diff --git a/Assets/Scripts/UI/UIScore.cs b/Assets/Scripts/UI/UIScore.cs index 30dfd68d..bc346de6 100644 --- a/Assets/Scripts/UI/UIScore.cs +++ b/Assets/Scripts/UI/UIScore.cs @@ -6,6 +6,10 @@ namespace QFramework.Example { public class UIScoreData : UIPanelData { + /// + /// 只显示当前模块的评分 + /// + public bool onlyCurModule = false; } public partial class UIScore : UIPanel { @@ -63,14 +67,30 @@ namespace QFramework.Example protected override void OnOpen(IUIData uiData = null) { + mData = uiData as UIScoreData ?? new UIScoreData(); Content.RemoveAllChildren(); float sum = 0; float score = 0; - foreach (var moduleDict in ScoreController.Instance.moduleDict) + + bool onlyCur = false; + if (uiData == null) { - foreach (var item in moduleDict.Value.scoreDict) + if (bool.TryParse(Global.Instance.curModule.OnlyCurScore, out onlyCur) == false) + { + onlyCur = false; + } + } + else + { + onlyCur = mData.onlyCurModule; + } + + + if (onlyCur) + { + foreach (var item in ScoreController.Instance.GetCurScoreData()) { GameObject obj = GameObject.Instantiate(ItemPrefab.gameObject, Content); obj.transform.Find("Step").GetComponent().text = item.Value.step; @@ -81,6 +101,23 @@ namespace QFramework.Example score += item.Value.value; } } + else + { + foreach (var moduleDict in ScoreController.Instance.moduleDict) + { + foreach (var item in moduleDict.Value.scoreDict) + { + GameObject obj = GameObject.Instantiate(ItemPrefab.gameObject, Content); + obj.transform.Find("Step").GetComponent().text = item.Value.step; + obj.transform.Find("Name").GetComponent().text = item.Value.name; + obj.transform.Find("Sum").GetComponent().text = item.Value.sum; + obj.transform.Find("Score").GetComponent().text = item.Value.value.ToString(); + sum += float.Parse(item.Value.sum); + score += item.Value.value; + } + } + } + this.Score.text = score.ToString(); this.Sum.text = sum.ToString(); diff --git a/Assets/Scripts/Xml/XmlParser.cs b/Assets/Scripts/Xml/XmlParser.cs index 58602bab..580bf747 100644 --- a/Assets/Scripts/Xml/XmlParser.cs +++ b/Assets/Scripts/Xml/XmlParser.cs @@ -26,6 +26,7 @@ namespace XMLTool public string ModuleName { get; set; } public string Descript { get; set; } + public string OnlyCurScore { get; set; } public string Icon { get; set; } public List Operations { get; set; } @@ -269,6 +270,7 @@ namespace XMLTool module.type = moduleElement.Element("Type")?.Value; module.ModuleName = moduleElement.Element("Name")?.Value; module.Icon = moduleElement.Element("Icon")?.Value; + module.OnlyCurScore = moduleElement.Element("OnlyCurScore")?.Value; module.Descript = moduleElement.Element("Descript")?.Value.Trim(); module.Scene = moduleElement.Element("Scene")?.Value; @@ -1557,6 +1559,17 @@ namespace XMLTool newAction = act; } break; + case "ShowScore": + { + var act = new DictionaryAction(); + XAttribute onlyCurModule = action.Attribute("onlyCurModule"); + if (onlyCurModule != null) + { + act.args.Add("onlyCurModule", onlyCurModule.Value); + } + newAction = act; + } + break; default: newAction = new Action(); break; diff --git a/Doc/Xml閰嶇疆鏂囨。.xml b/Doc/Xml閰嶇疆鏂囨。.xml index 0d9a267b..2cc18340 100644 --- a/Doc/Xml閰嶇疆鏂囨。.xml +++ b/Doc/Xml閰嶇疆鏂囨。.xml @@ -18,6 +18,9 @@ + + + Study + + false