Merge remote-tracking branch 'origin/master' into AnHui_BaoShi
This commit is contained in:
commit
805c2f79b8
@ -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;
|
||||
|
||||
82
Assets/Scripts/Actions/ShowScoreAction.cs
Normal file
82
Assets/Scripts/Actions/ShowScoreAction.cs
Normal file
@ -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<ShowScoreAction> mPool =
|
||||
new SimpleObjectPool<ShowScoreAction>(() => new ShowScoreAction(), null, 10);
|
||||
|
||||
Dictionary<string, string> datas;
|
||||
public static ShowScoreAction Allocate(Dictionary<string, string> 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<UIScore>(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; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
3
Assets/Scripts/Actions/ShowScoreAction.cs.meta
Normal file
3
Assets/Scripts/Actions/ShowScoreAction.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ba81906fe012d2468c5a69a833ed765
|
||||
timeCreated: 1647655796
|
||||
145
Assets/Scripts/Editor/LowercaseFileRenamer.cs
Normal file
145
Assets/Scripts/Editor/LowercaseFileRenamer.cs
Normal file
@ -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
|
||||
11
Assets/Scripts/Editor/LowercaseFileRenamer.cs.meta
Normal file
11
Assets/Scripts/Editor/LowercaseFileRenamer.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fc1a350612ff074eb9880438ed8d526
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,10 @@ namespace QFramework.Example
|
||||
{
|
||||
public class UIScoreData : UIPanelData
|
||||
{
|
||||
/// <summary>
|
||||
/// Ö»ÏÔʾµ±Ç°Ä£¿éµÄÆÀ·Ö
|
||||
/// </summary>
|
||||
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<TextMeshProUGUI>().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<TextMeshProUGUI>().text = item.Value.step;
|
||||
obj.transform.Find("Name").GetComponent<TextMeshProUGUI>().text = item.Value.name;
|
||||
obj.transform.Find("Sum").GetComponent<TextMeshProUGUI>().text = item.Value.sum;
|
||||
obj.transform.Find("Score").GetComponent<TextMeshProUGUI>().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();
|
||||
|
||||
@ -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<Operation> 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;
|
||||
|
||||
@ -18,6 +18,9 @@
|
||||
<!--执行下一步左侧步骤列表 默认开始的时候为-1步 要主动调用一次才到第1步-->
|
||||
<Action type="NextOperation"></Action>
|
||||
|
||||
<!--显示得分UI界面 onlyCurModule 是否仅显示当前模块成绩 默认为false-->
|
||||
<Action type="ShowScore" onlyCurModule="true"></Action>
|
||||
|
||||
<!--切换operation模块 使用此功能 operation的配置中必须有name属性
|
||||
name为operation配置中的name
|
||||
执行此行后 不需要在执行NextOperationAction 框架底层执行了
|
||||
@ -262,6 +265,8 @@
|
||||
<Scene>Scene</Scene>
|
||||
<!--Study学习模式 Exam实训模式 All都有-->
|
||||
<Type>Study</Type>
|
||||
<!--右上角显示成绩的时候 是否只显示当前模块的-->
|
||||
<OnlyCurScore>false</OnlyCurScore>
|
||||
<!--
|
||||
用于显示模块选择页面的 模块图标
|
||||
图片存放于Data/Image/路径下面 可以自己构建子路径
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user