diff --git a/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.AssetsAutoSetting.cs b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.AssetsAutoSetting.cs new file mode 100644 index 00000000..8264a2dc --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.AssetsAutoSetting.cs @@ -0,0 +1,42 @@ +#if UNITY_EDITOR +using System.IO; +using UnityEditor; +using UnityEngine; + +public class AxiProjectTools_AssetsAutoSetting : EditorWindow +{ + [MenuItem("Axibug移植工具/AssetsAutoSetting/自动设置TextureMaxSize为图片大小1倍")] + public static void AutoSettTextureSize_1x() { SetTextureSite(1f); } + + [MenuItem("Axibug移植工具/AssetsAutoSetting/自动设置TextureMaxSize为图片大小2分之1倍")] + public static void AutoSettTextureSize_1_2x() { SetTextureSite(1f / 2f); } + [MenuItem("Axibug移植工具/AssetsAutoSetting/自动设置TextureMaxSize为图片大小4分之1倍")] + public static void AutoSettTextureSize_1_4x() { SetTextureSite(1f / 4f); } + + public static void SetTextureSite(float Scale) + { + Texture2D[] textures = Selection.GetFiltered(SelectionMode.DeepAssets); + if (textures.Length == 0) + { + Debug.LogWarning("请先选择目录,或者Texture资源"); + return; + } + + AssetDatabase.StartAssetEditing(); // 开启批量编辑模式 + foreach (var texture in textures) + { + string path = AssetDatabase.GetAssetPath(texture); + TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter; + if (importer != null) + { + int size = Mathf.Max(texture.width, texture.height); + int maxsize = Mathf.ClosestPowerOfTwo((int)(size * Scale)); // Unity内置方法适配2的幂次方 + importer.maxTextureSize = maxsize; + importer.SaveAndReimport(); + } + } + AssetDatabase.StopAssetEditing(); // 结束批量编辑 + Debug.Log($"Updated {textures.Length} textures."); + } +} +#endif \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.AssetsAutoSetting.cs.meta b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.AssetsAutoSetting.cs.meta new file mode 100644 index 00000000..6b3186ae --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.AssetsAutoSetting.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: dc0741a79e74f96449a260406f239066 \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.Statistics.cs b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.Statistics.cs new file mode 100644 index 00000000..a1e3c1ec --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.Statistics.cs @@ -0,0 +1,840 @@ +#if UNITY_EDITOR && UNITY_2020_1_OR_NEWER +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using UnityEditor; +using UnityEngine; + +public class AxiProjectToolsStatistics : EditorWindow +{ + static string cachecfgPath = "Assets/AxiStatisticsDatas.asset"; + static Dictionary dictTempData = new Dictionary(); + + static void ClearTempData() + { + dictTempData.Clear(); + } + static string GetRootTempKey(int type, string rootName) + { + return type + "_" + rootName; + } + + + // 添加Hierarchy右键菜单项 + [MenuItem("GameObject/AxiStatistics/GetAxiNodeHash", false, 10)] + public static void GetAxiNodeHash() + { + // 获取当前右键选中的Transform + Transform selectedTransform = Selection.activeTransform; + if (selectedTransform != null) + { + Debug.Log("选中的对象"+selectedTransform.name+",Hash=>"+ GetNodeDataHash(selectedTransform,true)); + } + } + + static int GetNodeDataHash(Transform trans,bool bLog = false) + { + long hashplus = 0; + hashplus += trans.position.GetHashCode(); + hashplus += trans.localPosition.GetHashCode(); + + +#if UNITY_2017_1_OR_NEWER + int count = trans.childCount; +#else + int count = trans.GetChildCount(); +#endif + hashplus += count; + for (int i = 0; i < count; i++) + { + hashplus += trans.GetChild(i).name.GetHashCode(); + } + + + if (bLog) + { + //Debug.Log("trans.position.GetHashCode()=>" + trans.position.GetHashCode()); + //Debug.Log("trans.localPosition.GetHashCode()=>" + trans.localPosition.GetHashCode()); + //Debug.Log("childCount =>" + count); + //Debug.Log("hashplus =>" + hashplus); + //Debug.Log("hashplus.GetHashCode() =>" + hashplus.GetHashCode()); + } + + return hashplus.GetHashCode(); + } + static int GetNodeLinkListHash(List nodes) + { + string hashplus = string.Empty; + + foreach (var node in nodes) + { + hashplus += node.Name; + hashplus += node.Idx.ToString(); + } + + return hashplus.GetHashCode(); + } + + static string GetNodeLinkListStr(List nodes) + { + string linkstr = string.Empty; + + foreach (var node in nodes) + { + linkstr += "/"; + linkstr += node.Name; + linkstr += "[" + node.Idx + "]"; + } + return linkstr; + } + + static void AddComponentData(int _type, string _rootPath, AxiStatistics_Node_Component _comdata, string _nodepath, Component lastcom) + { + string rootKey = GetRootTempKey(_type, _rootPath); + + if (!dictTempData.ContainsKey(rootKey)) + { + dictTempData[rootKey] = new AxiStatisticsDatas() { type = _type, FullPath = _rootPath, nodes = new List() }; + } + AxiStatisticsDatas rootData = dictTempData[rootKey]; + + List link = new List(); + if (lastcom.transform.parent != null) + { + Transform currNode = lastcom.transform; + while (currNode != null) + { + //最顶层了 + if (currNode.parent == null) + { + link.Insert(0, new AxiStatistics_Node_Link() + { + NodeHash = GetNodeDataHash(currNode), + Idx = 0, + OnlyOne = true, + Name = currNode.gameObject.name + }); + break; + } + + int thisNameAllCount = 0; + int thisNodeIdx = -1; +#if UNITY_2017_1_OR_NEWER + int count = currNode.parent.childCount; +#else + int count = currNode.parent.GetChildCount(); +#endif + bool bFind = false; + for (int i = 0; i < count; i++) + { + GameObject checkGobj = currNode.parent.GetChild(i).gameObject; + if (checkGobj.name == currNode.name) + { + thisNameAllCount++; + if (checkGobj == currNode.gameObject) + { + thisNodeIdx = thisNameAllCount - 1; + bFind = true; + } + } + } + + if (bFind) + { + link.Insert(0, new AxiStatistics_Node_Link() + { + NodeHash = GetNodeDataHash(currNode), + Idx = thisNodeIdx, + OnlyOne = thisNameAllCount == 1, + Name = currNode.gameObject.name + }); + currNode = currNode.parent; + } + else + break; + } + } + else + { + link.Insert(0, new AxiStatistics_Node_Link() + { + NodeHash = GetNodeDataHash(lastcom.transform), + Idx = 0, + OnlyOne = true, + Name = lastcom.gameObject.name + }); + } + + int linkhash = GetNodeLinkListHash(link); + AxiStatistics_Node nodeData = rootData.nodes.Where(w => w.LinkHash == linkhash).FirstOrDefault(); + if (nodeData == null) + { + nodeData = new AxiStatistics_Node(); + nodeData.Name = Path.GetFileName(_nodepath); + //nodeData.NodeFullPath = _nodepath; + nodeData.components = new List(); + //nodeData.NodeIdx = thisNodeIdx; + //nodeData.NodeIdxOnlyOne = bNodeIdxOnlyOne; + + nodeData.link = link; + nodeData.LinkHash = linkhash; + nodeData.LinkFullStr = GetNodeLinkListStr(link); + + rootData.nodes.Add(nodeData); + } + + nodeData.components.Add(_comdata); + } + + static bool CheckCom(Component[] allcoms, int comRealIdx, int _type, string _rootPath, Component com, string nodepath) + { + if (com is BoxCollider2D) + { + BoxCollider2D bc = com as BoxCollider2D; +#if UNITY_2017_1_OR_NEWER + Debug.Log(nodepath + "BoxCollider2D->center=>(" + bc.offset.x + "," + bc.offset.y + ") size=>(" + bc.size.x + "," + bc.size.y + ""); +#else + Debug.Log(nodepath +"BoxCollider2D->center=>("+ bc.center.x+","+bc.center.y+") size=>("+ bc.size.x+","+bc.size.y+""); +#endif + AxiStatistics_Node_Component _com = new AxiStatistics_Node_Component(); + _com.type = typeof(BoxCollider2D).ToString(); +#if UNITY_2017_1_OR_NEWER + _com.center = bc.offset; +#else + _com.center = bc.center; +#endif + _com.size = bc.size; + SetCompnentIdxNum(_com, allcoms, comRealIdx, bc); + AddComponentData(_type, _rootPath, _com, nodepath, com); + } + if (com is Rigidbody2D) + { + Rigidbody2D rig2d = com as Rigidbody2D; + Debug.Log(_rootPath + "Rigidbody2D->simulated=>(" + rig2d.simulated + ")"); + Debug.Log(_rootPath + "Rigidbody2D->IsSleeping=>(" + rig2d.isKinematic.ToString() + ")"); + + AxiStatistics_Node_Component _com = new AxiStatistics_Node_Component(); + _com.type = typeof(Rigidbody2D).ToString(); + _com.isKinematic = rig2d.isKinematic; + _com.simulated = rig2d.simulated; + _com.gravityScale = rig2d.gravityScale; + SetCompnentIdxNum(_com, allcoms, comRealIdx, rig2d); + AddComponentData(_type, _rootPath, _com, nodepath, com); + } + return true; + } + + /// + /// 找出同类Idx + /// + /// + /// + /// + /// + /// + static void SetCompnentIdxNum(AxiStatistics_Node_Component _comData, Component[] allcoms, int comRealIdx, T com) where T : Component + { + int ComIdxNum; + bool ComTypeIsOnlyOne = false; + int TCount = com.transform.GetComponents().Length; + if (TCount == 1) + { + ComIdxNum = 0; + ComTypeIsOnlyOne = true; + } + else if (TCount < 1) + { + Debug.LogError("找不到,不应该"); + ComIdxNum = -1; + } + + ComIdxNum = -1; + for (int i = 0; i < allcoms.Length; i++) + { + //他自己自然是了 + if (i == comRealIdx) + { + ComIdxNum++; + break; + } + if (allcoms[i] is T) + ComIdxNum++; + } + + _comData.ComIdxNum = ComIdxNum; + _comData.ComTypeOnlyOne = ComTypeIsOnlyOne; + } + + [MenuItem("Axibug移植工具/Statistics/[1]统计所有预制体和场景下的Collider和RigBody")] + + public static void StatisticsCollider() + { + ClearTempData(); + StatisticsCollider(); + StatisticsCollider(); + + AxiStatisticsCache cache = ScriptableObject.CreateInstance(); + foreach (var data in dictTempData) + cache.caches.Add(data.Value); + AssetDatabase.CreateAsset(cache, cachecfgPath); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + } + + public static void StatisticsCollider() where T : Component + { + AxiProjectTools.GoTAxiProjectToolsSence(); + + string[] sceneGuids = AssetDatabase.FindAssets("t:scene"); + foreach (string guid in sceneGuids) + { + string path = AssetDatabase.GUIDToAssetPath(guid); + if (path.Contains(AxiProjectTools.toolSenceName)) + continue; + +#if UNITY_4_6 + EditorApplication.OpenScene(path); +#else + UnityEditor.SceneManagement.EditorSceneManager.OpenScene(path); +#endif + + // 创建一个列表来存储根节点 + List rootNodes = new List(); + + // 遍历场景中的所有对象 + GameObject[] allObjects = FindObjectsOfType(); + foreach (GameObject obj in allObjects) + { + // 检查对象是否有父对象 + if (obj.transform.parent == null) + { + // 如果没有父对象,则它是一个根节点 + rootNodes.Add(obj); + } + } + + foreach (var node in rootNodes) + LoopPrefabNode(0, path, path, node, 0); + + } + string[] prefabGuids = AssetDatabase.FindAssets("t:Prefab"); + foreach (string guid in prefabGuids) + { + string path = AssetDatabase.GUIDToAssetPath(guid); + GetPrefab(path); + } + + AxiProjectTools.GoTAxiProjectToolsSence(); + Debug.Log("处理完毕 统计所有预制体和场景下的" + typeof(T).FullName + ""); + } + + static void GetPrefab(string path) where T : Component + { +#if UNITY_4_6 + GameObject prefab = AssetDatabase.LoadAssetAtPath(path,typeof(GameObject)) as GameObject; +#else + GameObject prefab = AssetDatabase.LoadAssetAtPath(path); +#endif + + LoopPrefabNode(1, path, path, prefab.gameObject, 0); + } + + static void LoopPrefabNode(int _type, string _rootPath, string noderootPath, GameObject trans, int depth) where T : Component + { + // #if UNITY_2018_4_OR_NEWER + string nodename = noderootPath + "/" + trans.name; + GameObject prefabRoot = trans.gameObject; + + Component[] components = prefabRoot.GetComponents(); + for (int i = 0; i < components.Length; i++) + { + var com = components[i]; + + if (com == null) + continue; + + T comobj = com as T; + if (comobj == null) + continue; + + if (CheckCom(components, i, _type, _rootPath, comobj, nodename)) + continue; + } + + //遍历 + foreach (Transform child in trans.transform) + LoopPrefabNode(_type, _rootPath, nodename, child.gameObject, depth + 1); + //#else + // Debug.Log("低版本不要执行本函数"); + //#endif + } + +#if UNITY_2017_1_OR_NEWER + [MenuItem("Axibug移植工具/Statistics/[2]通过记录,对组件进行修补")] + public static void RepairRigBodyByStatistics() + { + List errLog = new List(); + List doneLog = new List(); + List> NeedRepair = new List>(); + List> FinishRepair = new List>(); + string CurrScenePath = string.Empty; + AxiProjectTools.GoTAxiProjectToolsSence(); +#if UNITY_4_6 + AxiStatisticsCache data = AssetDatabase.LoadAssetAtPath(cachecfgPath,typeof(AxiStatisticsCache)) as AxiStatisticsCache; +#else + AxiStatisticsCache data = AssetDatabase.LoadAssetAtPath(cachecfgPath); +#endif + string[] sceneGuids = AssetDatabase.FindAssets("t:scene"); + List ScenePath = new List(); + List SceneName = new List(); + foreach (string guid in sceneGuids) + { + string path = AssetDatabase.GUIDToAssetPath(guid); + if (path.Contains(AxiProjectTools.toolSenceName)) + continue; + ScenePath.Add(path); + SceneName.Add(Path.GetFileName(path)); + } + + string[] prefabGuids = AssetDatabase.FindAssets("t:prefab"); + List prefabPath = new List(); + List prefabName = new List(); + foreach (string guid in prefabGuids) + { + string path = AssetDatabase.GUIDToAssetPath(guid); + prefabPath.Add(path); + prefabName.Add(Path.GetFileName(path)); + } + + foreach (var cache in data.caches.OrderBy(w => w.type)) + { + //场景 + if (cache.type == 0) + { + #region 场景加载 + string targetName = Path.GetFileName(cache.FullPath); + int Idx = SceneName.IndexOf(targetName); + if (Idx < 0) + { + Debug.LogError(targetName + "[Repair]找不到对应资源"); + continue; + } + string targetpath = ScenePath[Idx]; + + //保证场景切换 + if (!string.Equals(CurrScenePath, targetpath)) + { +#if UNITY_4_6 + EditorApplication.OpenScene(targetpath); +#else + UnityEditor.SceneManagement.EditorSceneManager.OpenScene(targetpath); +#endif + } + CurrScenePath = targetpath; + #endregion + + int DirtyCount = 0; + foreach (var node in cache.nodes) + { + GameObject targetNodePathObj = GetNodeByLink(cache.FullPath, node.link, out string errStr); + if (targetNodePathObj == null) + { + errLog.Add(errStr); + continue; + } + + /* + string targetNodePath = node.NodeFullPath.Substring(cache.FullPath.Length, node.NodeFullPath.Length - cache.FullPath.Length); + + //GameObject targetNodePathObj = GameObject.Find(targetNodePath); + GameObject targetNodePathObj = GetNodeByIdx(node, targetNodePath); + + if (targetNodePathObj == null) + { + string err = "[Repair]" + node.NodeFullPath + "找不到对应节点"; + errLog.Add(err); + Debug.LogError(err); + continue; + } + */ + foreach (var com in node.components) + { + if (RepairComponent(node.LinkFullStr, targetNodePathObj, com, out var errlog)) + { + NeedRepair.Add(new ValueTuple($"{cache.FullPath}:{node.LinkFullStr}", $"{com.type}[{com.ComIdxNum}]")); + DirtyCount++; + } + errLog.AddRange(errlog); + } + } + if (DirtyCount > 0) + { + Debug.Log($"[Repair][场景处理]{cache.FullPath}共{DirtyCount}个需要处理"); + + + // 获取当前打开的场景 + var activeScene = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene(); + + // 保存场景 + UnityEditor.SceneManagement.EditorSceneManager.SaveScene(activeScene); + + Debug.Log("场景已保存: " + activeScene.path); + string donestr = $"[Repair][场景处理成功]{targetpath},共{DirtyCount}个"; + doneLog.Add(donestr); + + } + } + else if (cache.type == 1) + { + string targetpath = cache.FullPath; + + //来到空场景 + if (!string.IsNullOrEmpty(CurrScenePath)) + { + AxiProjectTools.GoTAxiProjectToolsSence(); + CurrScenePath = string.Empty; + } + + + GameObject prefabInstance = AssetDatabase.LoadAssetAtPath(targetpath); + if (prefabInstance == null) + { + Debug.LogError($"[Repair]Failed to load prefab at path: {prefabPath}"); + return; + } + + var obj = GameObject.Instantiate(prefabInstance, null); + + int DirtyCount = 0; + foreach (var node in cache.nodes) + { + GameObject targetNodePathObj = GetNodeByLink(cache.FullPath, node.link, out string errStr, obj); + + if (targetNodePathObj == null) + { + errLog.Add(errStr); + continue; + } + //if (node.NodeFullPath == targetpath + "/" + Path.GetFileNameWithoutExtension(targetpath)) + //{ + // //预制体自己就是目标 + // targetNodePathObj = obj; + //} + //else + //{ + // string targetNodePath = node.NodeFullPath.Substring(cache.FullPath.Length + prefabInstance.name.Length + 2, node.NodeFullPath.Length - cache.FullPath.Length - prefabInstance.name.Length - 2); + // //targetNodePathObj = obj.transform.Find(targetNodePath)?.gameObject; + // targetNodePathObj = GetNodeByIdx(node, targetNodePath, obj); + + // if (targetNodePathObj == null) + // { + // Debug.LogError("[Repair]" + targetNodePath + "找不到对应节点"); + // continue; + // } + //} + + + foreach (var com in node.components) + { + if (RepairComponent(node.LinkFullStr, targetNodePathObj, com, out var errlog)) + { + NeedRepair.Add(new ValueTuple($"{cache.FullPath}:{node.LinkFullStr}", $"{com.type}[{com.ComIdxNum}]")); + DirtyCount++; + } + + errLog.AddRange(errlog); + } + } + + if (DirtyCount > 0) + { + Debug.Log($"[Repair][预制体处理]{targetpath}共{DirtyCount}个需要处理"); + PrefabUtility.SaveAsPrefabAsset(obj, targetpath); + string donestr = $"[Repair][预制体处理成功]{targetpath},共{DirtyCount}个"; + doneLog.Add(donestr); + } + GameObject.DestroyImmediate(obj); + } + } + + AxiProjectTools.GoTAxiProjectToolsSence(); + StringBuilder sb = new StringBuilder(); + sb.AppendLine("[Repair][统计]:"); + sb.AppendLine("----处理成功----"); + foreach (var val in doneLog.OrderBy(w => w)) + { + sb.AppendLine(val); + } + sb.AppendLine("----异常统计----"); + foreach (var val in errLog.OrderBy(w => w)) + { + sb.AppendLine(val); + } + sb.AppendLine("----需要处理----"); + foreach (var val in NeedRepair.OrderBy(w => w.Item1)) + { + sb.AppendLine($"{val.Item1}=>{val.Item2}"); + } + Debug.Log($"{sb}"); + + File.WriteAllText("Assets/AxiNeedRepair.txt", sb.ToString()); + } + + + // static GameObject GetNodeByIdx(AxiStatistics_Node nodedata, string targetNodePath, GameObject root = null) + // { + // GameObject targetNodePathObj; + + // if (root == null) + // targetNodePathObj = GameObject.Find(targetNodePath); + // else + // targetNodePathObj = root.transform.Find(targetNodePath)?.gameObject; + + // if (targetNodePathObj == null) + // return null; + + // string targetName = targetNodePathObj.name; + // int currIdx = -1; + // if (!nodedata.NodeIdxOnlyOne) + // { + // if (targetNodePathObj.transform.parent != null) + // { + //#if UNITY_2017_1_OR_NEWER + // int count = targetNodePathObj.transform.parent.childCount; + //#else + // int count = targetNodePathObj.transform.parent.GetChildCount(); + //#endif + // for (int i = 0; i < count; i++) + // { + // GameObject checkGobj = targetNodePathObj.transform.parent.GetChild(i).gameObject; + // if (checkGobj.name == targetName) + // { + // currIdx++; + // if (nodedata.NodeIdx == currIdx) + // { + // targetNodePathObj = checkGobj; + // break; + // } + // } + // } + // } + // } + + // return targetNodePathObj; + // } + + + static GameObject GetNodeByLink(string rootPath, List linklist, out string errStr, GameObject PrefabRoot = null) + { + List temp_useddlink = new List(); + if (linklist.Count < 1) + { + errStr = $"[Repair] Link 为空"; + Debug.LogError(errStr); + return null; + } + + temp_useddlink.Add(linklist[0]); + GameObject currRoot; + + if (PrefabRoot == null) + currRoot = GameObject.Find(linklist[0].Name); + else + { + currRoot = PrefabRoot; + //currRoot = PrefabRoot.transform.Find(linklist[0].Name)?.gameObject; + } + + if (currRoot == null) + { + errStr = $"[Repair] 根节点找不到{rootPath}:{GetNodeLinkListStr(linklist)} => null"; + Debug.LogError(errStr); + return null; + } + + for (int link_i = 1; link_i < linklist.Count; link_i++) + { + AxiStatistics_Node_Link targetLink = linklist[link_i]; + temp_useddlink.Add(targetLink); + GameObject findNode = null; +#if UNITY_2017_1_OR_NEWER + int count = currRoot.transform.childCount; +#else + int count = currNode.transform.GetChildCount(); +#endif + + if (targetLink.OnlyOne) + { + for (int i = 0; i < count; i++) + { + GameObject checkGobj = currRoot.transform.GetChild(i).gameObject; + if (checkGobj.name == targetLink.Name) + { + findNode = checkGobj; + break; + } + } + } + else + { + + Dictionary tempHash2Node = new Dictionary(); + List tempGobjList = new List(); + bool HashDrity = false; + for (int i = 0; i < count; i++) + { + GameObject checkGobj = currRoot.transform.GetChild(i).gameObject; + if (checkGobj.name == targetLink.Name) + { + int temphash = GetNodeDataHash(checkGobj.transform); + if (!tempHash2Node.ContainsKey(temphash)) + { + tempHash2Node.Add(GetNodeDataHash(checkGobj.transform), checkGobj); + } + else + { + HashDrity = true; + } + tempGobjList.Add(checkGobj); + } + } + + //Hash严格模式 + if (!HashDrity && tempHash2Node.TryGetValue(targetLink.NodeHash, out var val)) + { + findNode = val; + } + //下标模式 + else + { + if (targetLink.Idx < 0 || tempGobjList.Count == 0 || (tempGobjList.Count != 0 && targetLink.Idx >= tempGobjList.Count)) + { + errStr = $"[Repair]link 下标模式 找不到=>{rootPath}:{GetNodeLinkListStr(temp_useddlink)}[{targetLink.Idx}] => 完整链路{rootPath}:{GetNodeLinkListStr(linklist)}"; + Debug.LogError(errStr); + return null; + } + else + { + findNode = tempGobjList[targetLink.Idx]; + } + } + } + + + currRoot = findNode; + if (currRoot == null) + break; + } + + if (currRoot == null) + { + errStr = $"[Repair]link 找不到[{rootPath}:{GetNodeLinkListStr(temp_useddlink)}] => 完整链路{rootPath}:{GetNodeLinkListStr(linklist)}"; + Debug.LogError(errStr); + return null; + } + else + { + errStr = string.Empty; + return currRoot; + } + } + + static bool RepairComponent(string NodePath, GameObject targetNodePathObj, AxiStatistics_Node_Component comdata, out List Errlog) + { + Errlog = new List(); + string err; + bool Dirty = false; + if (comdata.type == typeof(Rigidbody2D).ToString()) + { + Rigidbody2D rg2d = GetCompnentById(targetNodePathObj, comdata); + if (rg2d == null) + { + err = $"[Repair]{NodePath}=> Rigidbody2D[{comdata.ComIdxNum}] == null"; + Debug.LogError(err); + Errlog.Add(err); + Dirty = false; + } + + /* +与新版Unity的差异​ +​无BodyType选项​:Unity 4.6.7中所有Rigidbody2D默认等效于新版的Dynamic类型(受重力影响),但无法设置为Static或Kinematic。 +​无Simulated选项​:只要物体启用了Rigidbody2D组件且Gravity Scale > 0,就会受重力作用。 + + 所以,一旦老版本gravityScale > 0,就受重力作用,直接设置新版本这边:simulated = true;bodyType = RigidbodyType2D.Dynamic; + */ + + + if (rg2d.gravityScale != comdata.gravityScale) + { + Debug.Log($"[Repair]{NodePath}=> Rigidbody2D[{comdata.ComIdxNum}] simulated:{rg2d.gravityScale} != :{comdata.gravityScale} rg2d.bodyType => {rg2d.bodyType} "); + + rg2d.gravityScale = comdata.gravityScale; + Dirty = true; + } + + //if (rg2d.gravityScale > 0 && (!rg2d.simulated || rg2d.bodyType != RigidbodyType2D.Dynamic)) + if (!rg2d.simulated || rg2d.bodyType != RigidbodyType2D.Dynamic) + { + Debug.Log($"[Repair]{NodePath}=> Rigidbody2D[{comdata.ComIdxNum}] simulated:{rg2d.simulated} != :{comdata.simulated} rg2d.bodyType => {rg2d.bodyType} "); + + rg2d.simulated = true; + rg2d.bodyType = RigidbodyType2D.Dynamic; + Dirty = true; + } + } + else if (comdata.type == typeof(BoxCollider2D).ToString()) + { + BoxCollider2D bc = GetCompnentById(targetNodePathObj, comdata); + if (bc == null) + { + err = $"[Repair]{NodePath}=> BoxCollider2D[{comdata.ComIdxNum}] == null"; + Debug.LogError(err); + Errlog.Add(err); + Dirty = false; + } + else + { + if (bc.size != comdata.size) + { + Debug.Log($"[Repair]{NodePath} BoxCollider2D[{comdata.ComIdxNum}] => size:{bc.size} != {comdata.size} "); + bc.size = comdata.size; + Dirty = true; + } + if (bc.offset != comdata.center) + { + Debug.Log($"[Repair]{NodePath} BoxCollider2D[{comdata.ComIdxNum}] => offset:{bc.offset} != center{comdata.center} "); + bc.offset = comdata.center; + Dirty = true; + } + + if (Dirty) + { + bc.size = comdata.size; + bc.offset = comdata.center; + } + } + } + + + return Dirty; + } + + static T GetCompnentById(GameObject gobj, AxiStatistics_Node_Component node) where T : Component + { + if (node.ComIdxNum == 0) + return gobj.GetComponent(); + else if (node.ComIdxNum > 0) + { + T[] coms = gobj.GetComponents(); + if (node.ComIdxNum < coms.Length) + return coms[node.ComIdxNum]; + } + + return null; + } + +#endif +} +#endif \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.Statistics.cs.meta b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.Statistics.cs.meta new file mode 100644 index 00000000..729b6c29 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.Statistics.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 32aabdd304d2c4d47b8ef660f672ead1 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.cs b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.cs index fa31dc04..0f2cf0e1 100644 --- a/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.cs +++ b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiProjectTools.cs @@ -3,19 +3,18 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text.RegularExpressions; using UnityEditor; -using UnityEditor.SceneManagement; using UnityEngine; -using UnityEngine.SceneManagement; public class AxiProjectTools : EditorWindow { static string cachecfgPath = "Assets/AxiComToolCache.asset"; - static string toolSenceName = "AxiProjectTools"; - static string outCsDir = Application.dataPath + "/AxiCom/"; - static Dictionary ComType2GUID = new Dictionary(); - - static void GoTAxiProjectToolsSence() + public static string toolSenceName = "AxiProjectTools"; + public static string outCsDir = Application.dataPath + "/AxiCom/"; + public static Dictionary ComType2GUID = new Dictionary(); + + public static void GoTAxiProjectToolsSence() { string[] sceneGuids = AssetDatabase.FindAssets("t:scene"); foreach (string guid in sceneGuids) @@ -23,12 +22,16 @@ public class AxiProjectTools : EditorWindow string path = AssetDatabase.GUIDToAssetPath(guid); if (path.Contains(toolSenceName)) { - EditorSceneManager.OpenScene(path); + #if UNITY_4_6 + EditorApplication.OpenScene(path); + #else + UnityEditor.SceneManagement.EditorSceneManager.OpenScene(path); + #endif return; } } } - + [MenuItem("Axibug移植工具/ToLowVersionUnity/[1]采集所有预制体和场景下的UGUI组件")] public static void Part1() { @@ -40,12 +43,16 @@ public class AxiProjectTools : EditorWindow string path = AssetDatabase.GUIDToAssetPath(guid); if (path.Contains(toolSenceName)) continue; - - EditorSceneManager.OpenScene(path); - + + #if UNITY_4_6 + EditorApplication.OpenScene(path); + #else + UnityEditor.SceneManagement.EditorSceneManager.OpenScene(path); + #endif + // 创建一个列表来存储根节点 List rootNodes = new List(); - + // 遍历场景中的所有对象 GameObject[] allObjects = FindObjectsOfType(); foreach (GameObject obj in allObjects) @@ -57,19 +64,19 @@ public class AxiProjectTools : EditorWindow rootNodes.Add(obj); } } - + foreach (var node in rootNodes) LoopPrefabNode(path, node, 0); } - - + + string[] prefabGuids = AssetDatabase.FindAssets("t:Prefab"); foreach (string guid in prefabGuids) { string path = AssetDatabase.GUIDToAssetPath(guid); GetPrefab(path); } - + AxiPrefabCache cache = ScriptableObject.CreateInstance(); foreach (var data in ComType2GUID) cache.caches.Add(data.Value); @@ -79,66 +86,88 @@ public class AxiProjectTools : EditorWindow GoTAxiProjectToolsSence(); Debug.Log("处理完毕 [1]采集所有预制体和场景下的UGUI组件"); } - + static void GetPrefab(string path) - { + { + #if UNITY_4_6 + GameObject prefab = AssetDatabase.LoadAssetAtPath(path,typeof(GameObject)) as GameObject; + #else GameObject prefab = AssetDatabase.LoadAssetAtPath(path); + #endif + LoopPrefabNode(path, prefab.gameObject, 0); } static void LoopPrefabNode(string rootPath, GameObject trans, int depth) { - string nodename = $"{rootPath}>{trans.name}"; -#if UNITY_2018_4_OR_NEWER - GameObject prefabRoot = trans.gameObject; - int comCount = prefabRoot.GetComponentCount(); - for (int i = 0; i < comCount; i++) - { - var com = prefabRoot.GetComponentAtIndex(i); - if (com == null) - continue; - - MonoBehaviour monoCom = com as MonoBehaviour; - if (monoCom == null) - continue; - Type monoType = monoCom.GetType(); - if (!monoType.Assembly.FullName.Contains("UnityEngine.UI")) - continue; - // 获取MonoScript资源 - MonoScript monoScript = MonoScript.FromMonoBehaviour(monoCom); - if (monoScript != null) - { - // 获取MonoScript资源的GUID - string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(monoScript)); - Debug.Log($"{nodename} | [{monoType.Name}] {guid}({monoType.FullName})"); - ComType2GUID[monoType.FullName] = - new AxiPrefabCache_Com2GUID() - { - SrcFullName = monoType.FullName, - SrcName = monoType.Name, - GUID = guid, - }; - } - else - { - Debug.LogError("!!!! 没得"); - } - } - - //遍历 - foreach (Transform child in trans.transform) - LoopPrefabNode(nodename, child.gameObject, depth + 1); -#else - Debug.Log("低版本不要执行本函数"); -#endif + // #if UNITY_2018_4_OR_NEWER + string nodename = rootPath + trans.name; + GameObject prefabRoot = trans.gameObject; + + Component[] components = prefabRoot.GetComponents(); + for (int i = 0; i < components.Length; i++) + { + var com = components[i]; + + if (com == null) + continue; + + MonoBehaviour monoCom = com as MonoBehaviour; + if (monoCom == null) + continue; + Type monoType = monoCom.GetType(); + if (!monoType.Assembly.FullName.Contains("UnityEngine.UI")) + continue; + // 获取MonoScript资源 + MonoScript monoScript = MonoScript.FromMonoBehaviour(monoCom); + if (monoScript != null) + { + // 获取MonoScript资源的GUID + string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(monoScript)); + Debug.Log(nodename+" | ["+monoType.Name+"] "+guid+"("+monoType.FullName+")"); + ComType2GUID[monoType.FullName] = + new AxiPrefabCache_Com2GUID() + { + SrcFullName = monoType.FullName, + SrcName = monoType.Name, + GUID = guid, + }; + } + else + { + Debug.LogError("!!!! 没得"); + } + } + + //遍历 + foreach (Transform child in trans.transform) + LoopPrefabNode(nodename, child.gameObject, depth + 1); + //#else + // Debug.Log("低版本不要执行本函数"); + //#endif } - + [MenuItem("Axibug移植工具/ToLowVersionUnity/[2]生成中间脚本代码")] public static void Part2() { + + #if UNITY_4_6 + if(System.IO.Directory.Exists(outCsDir)) + System.IO.Directory.Delete(outCsDir); + #else if (UnityEngine.Windows.Directory.Exists(outCsDir)) UnityEngine.Windows.Directory.Delete(outCsDir); + #endif + + Directory.CreateDirectory(outCsDir); + + + + #if UNITY_4_6 + AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath(cachecfgPath,typeof(AxiPrefabCache)) as AxiPrefabCache; + #else AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath(cachecfgPath); + #endif foreach (var data in cache.caches) { string toName = "Axi" + data.SrcName; @@ -160,12 +189,18 @@ public class AxiProjectTools : EditorWindow AssetDatabase.Refresh(); Debug.Log("处理完毕 [2]生成中间脚本代码"); } - + [MenuItem("Axibug移植工具/ToLowVersionUnity/[3]收集生成的脚本")] public static void Part3() { + #if UNITY_4_6 + AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath(cachecfgPath,typeof(AxiPrefabCache)) as AxiPrefabCache; + MonoScript[] allMonoScripts = (MonoScript[])Resources.FindObjectsOfTypeAll(typeof(MonoScript)); + #else AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath(cachecfgPath); List allMonoScripts = FindAllAssetsOfType(); + #endif + foreach (var data in cache.caches) { MonoScript monoScript = allMonoScripts.FirstOrDefault(w => w.name == data.ToName); @@ -183,18 +218,23 @@ public class AxiProjectTools : EditorWindow AssetDatabase.Refresh(); Debug.Log("处理完毕 [3]收集生成的脚本"); } - + static List FindAllAssetsOfType() where T : UnityEngine.Object { List assets = new List(); - + string[] allGuids = AssetDatabase.FindAssets(""); foreach (string guid in allGuids) { string path = AssetDatabase.GUIDToAssetPath(guid); if (path.EndsWith(".cs") || path.EndsWith(".js") || path.EndsWith(".boo")) // Unity支持多种脚本语言,但现代Unity主要使用C# { + #if UNITY_4_6 + T asset = AssetDatabase.LoadAssetAtPath(cachecfgPath,typeof(T)) as T; + #else T asset = AssetDatabase.LoadAssetAtPath(path); + #endif + if (asset != null) { assets.Add(asset); @@ -203,12 +243,18 @@ public class AxiProjectTools : EditorWindow } return assets; } - - + + [MenuItem("Axibug移植工具/ToLowVersionUnity/[4]替换所有预制体和场景中的组件")] public static void Part4() { + + #if UNITY_4_6 + AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath(cachecfgPath,typeof(AxiPrefabCache)) as AxiPrefabCache; + #else AxiPrefabCache cache = AssetDatabase.LoadAssetAtPath(cachecfgPath); + #endif + Dictionary tempReplaceDict = new Dictionary(); foreach (var data in cache.caches) { @@ -221,7 +267,7 @@ public class AxiProjectTools : EditorWindow AssetDatabase.Refresh(); Debug.Log("处理完毕 [4]替换所有预制体和场景中的组件"); } - + static void ProcessAllPrefabs(string form, Dictionary tempReplaceDict, bool reverse = false) { List prefabs = new List(); @@ -240,7 +286,7 @@ public class AxiProjectTools : EditorWindow } EditorUtility.ClearProgressBar(); } - + /// /// 替换值 /// @@ -257,17 +303,17 @@ public class AxiProjectTools : EditorWindow File.WriteAllLines(strFilePath, lines); } } - - + + [MenuItem("Axibug移植工具/ToLowVersionUnity/[5]UnPack所有嵌套预制体和场景中的预制体")] public static void UnpackPrefabs() { - -#if UNITY_2018_4_OR_NEWER - GoTAxiProjectToolsSence(); - string[] allAssetPaths = AssetDatabase.GetAllAssetPaths(); + + #if UNITY_2018_4_OR_NEWER + GoTAxiProjectToolsSence(); + string[] allAssetPaths = AssetDatabase.GetAllAssetPaths(); int prefabCount = 0; - + foreach (string path in allAssetPaths) { if (Path.GetExtension(path).Equals(".prefab")) @@ -278,59 +324,59 @@ public class AxiProjectTools : EditorWindow } } Debug.Log($"{prefabCount}个预制体Unpack"); - - string[] sceneGuids = AssetDatabase.FindAssets("t:scene"); - foreach (string guid in sceneGuids) - { - string path = AssetDatabase.GUIDToAssetPath(guid); - if (path.Contains(toolSenceName)) - continue; - - EditorSceneManager.OpenScene(path); - Scene currentScene = SceneManager.GetActiveScene(); - GameObject[] rootObjects = currentScene.GetRootGameObjects(); + + string[] sceneGuids = AssetDatabase.FindAssets("t:scene"); + foreach (string guid in sceneGuids) + { + string path = AssetDatabase.GUIDToAssetPath(guid); + if (path.Contains(toolSenceName)) + continue; + + UnityEditor.SceneManagement.EditorSceneManager.OpenScene(path); + UnityEngine.SceneManagement.Scene currentScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); + GameObject[] rootObjects = currentScene.GetRootGameObjects(); foreach (GameObject rootObj in rootObjects) - { - // 遍历场景中的所有对象 - TraverseHierarchy(rootObj); - } - // Save the scene // 获取当前打开的场景 - currentScene = EditorSceneManager.GetActiveScene(); - // 保存场景到文件(默认路径和名称) - bool success = EditorSceneManager.SaveScene(currentScene, currentScene.path); - - Debug.Log($"{currentScene.name}场景中 所有物体Unpack"); - } - - GoTAxiProjectToolsSence(); - Debug.Log("处理完毕 [5]UnPack所有预制体"); -#else - Debug.Log("低版本不要执行本函数"); -#endif - } - - static void UnpackPrefab(string prefabPath) + { + // 遍历场景中的所有对象 + TraverseHierarchy(rootObj); + } + // Save the scene // 获取当前打开的场景 + currentScene = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene(); + // 保存场景到文件(默认路径和名称) + bool success = UnityEditor.SceneManagement.EditorSceneManager.SaveScene(currentScene, currentScene.path); + + Debug.Log($"{currentScene.name}场景中 所有物体Unpack"); + } + + GoTAxiProjectToolsSence(); + Debug.Log("处理完毕 [5]UnPack所有预制体"); + #else + Debug.Log("低版本不要执行本函数"); + #endif + } + + static void UnpackPrefab(string prefabPath) { -#if UNITY_2018_4_OR_NEWER + #if UNITY_2018_4_OR_NEWER GameObject prefabInstance = AssetDatabase.LoadAssetAtPath(prefabPath); if (prefabInstance == null) { Debug.LogError($"Failed to load prefab at path: {prefabPath}"); return; } - + var obj = GameObject.Instantiate(prefabInstance, null); TraverseHierarchy(obj); PrefabUtility.SaveAsPrefabAsset(obj, prefabPath); GameObject.DestroyImmediate(obj); -#else + #else Debug.Log("低版本不要执行本函数"); -#endif + #endif } - + static void TraverseHierarchy(GameObject obj) { -#if UNITY_2018_4_OR_NEWER + #if UNITY_2018_4_OR_NEWER // 检查该对象是否是预制体的实例 if (PrefabUtility.IsPartOfPrefabInstance(obj)) { @@ -338,80 +384,123 @@ public class AxiProjectTools : EditorWindow PrefabUtility.UnpackPrefabInstance(obj, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction); Debug.Log("Prefab instance converted to game object: " + obj.name); } - + // 递归遍历子对象 for (int i = 0; i < obj.transform.childCount; i++) { TraverseHierarchy(obj.transform.GetChild(i).gameObject); } -#else + #else Debug.Log("低版本不要执行本函数"); -#endif + #endif } - [MenuItem("Axibug移植工具/ToLowVersionUnity/[6]修复Sprite")] - public static void FixMultipleMaterialSprites() - { - string[] guids = AssetDatabase.FindAssets("t:sprite"); - List spritesToFix = new List(); + [MenuItem("Axibug移植工具/ToLowVersionUnity/[6]修复Sprite")] + public static void FixMultipleMaterialSprites() + { + string[] guids = AssetDatabase.FindAssets("t:sprite"); + List spritesToFix = new List(); - foreach (string guid in guids) - { - string path = AssetDatabase.GUIDToAssetPath(guid); - Sprite sprite = AssetDatabase.LoadAssetAtPath(path); + foreach (string guid in guids) + { + string path = AssetDatabase.GUIDToAssetPath(guid); + Sprite sprite = AssetDatabase.LoadAssetAtPath(path); - // 检查是否有多个材质 - if (IsUsingMultipleMaterials(sprite)) - { - spritesToFix.Add(sprite); - Debug.Log("Found sprite with multiple materials: " + path); - } - } + // 检查是否有多个材质 + if (IsUsingMultipleMaterials(sprite)) + { + spritesToFix.Add(sprite); + Debug.Log("Found sprite with multiple materials: " + path); + } + } - // 修复每个找到的Sprite - foreach (var sprite in spritesToFix) - { - FixSprite(sprite); - } + // 修复每个找到的Sprite + foreach (var sprite in spritesToFix) + { + FixSprite(sprite); + } - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - Debug.Log("处理完毕 [6]修复Sprite"); - } + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + Debug.Log("处理完毕 [6]修复Sprite"); + } - private static bool IsUsingMultipleMaterials(Sprite sprite) - { - if (sprite == null) return false; + private static bool IsUsingMultipleMaterials(Sprite sprite) + { + if (sprite == null) return false; - // 获取精灵的材质 - var textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(sprite)) as TextureImporter; + // 获取精灵的材质 + var textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(sprite)) as TextureImporter; - return textureImporter != null && textureImporter.spriteImportMode == SpriteImportMode.Multiple; - } + return textureImporter != null && textureImporter.spriteImportMode == SpriteImportMode.Multiple; + } - private static void FixSprite(Sprite sprite) - { - // 获取Sprite的路径 - string path = AssetDatabase.GetAssetPath(sprite); - var textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; + private static void FixSprite(Sprite sprite) + { + // 获取Sprite的路径 + string path = AssetDatabase.GetAssetPath(sprite); + var textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; - if (textureImporter != null) - { - // 保存当前切割信息 - SpriteMetaData[] originalMetaData = textureImporter.spritesheet; + if (textureImporter != null) + { + // 保存当前切割信息 + SpriteMetaData[] originalMetaData = textureImporter.spritesheet; - // 临时禁用Sprite导入 - textureImporter.spriteImportMode = SpriteImportMode.None; - textureImporter.SaveAndReimport(); + // 临时禁用Sprite导入 + textureImporter.spriteImportMode = SpriteImportMode.None; + textureImporter.SaveAndReimport(); - // 重新启用Sprite导入并保持原样切割参数 - textureImporter.spriteImportMode = SpriteImportMode.Multiple; - textureImporter.spritesheet = originalMetaData; // 恢复原来的切割信息 + // 重新启用Sprite导入并保持原样切割参数 + textureImporter.spriteImportMode = SpriteImportMode.Multiple; + textureImporter.spritesheet = originalMetaData; // 恢复原来的切割信息 + + // 重新导入以应用更改 + textureImporter.SaveAndReimport(); + } + } + + + [MenuItem("Axibug移植工具/ToLowVersionUnity/[7]导入后低版本执行:修复组件挂载预制体依赖丢失")] + static void FixPrefabRefs() + { + // 1. 扫描所有预制体 + string[] prefabPaths = Directory.GetFiles("Assets", "*.prefab", SearchOption.AllDirectories); + foreach (var path in prefabPaths) FixRefTypeInFile(path); + + // 2. 处理场景文件 + string[] scenePaths = Directory.GetFiles("Assets", "*.unity", SearchOption.AllDirectories); + foreach (var path in scenePaths) FixRefTypeInFile(path); + + AssetDatabase.Refresh(); + Debug.Log("处理完毕 [5]导入低版本后:修复预制体依赖丢失"); + Debug.Log("修复完成!已处理" + prefabPaths.Length + "个预制体"); + } + + public static void FixRefTypeInFile(string filePath) + { + string content = File.ReadAllText(filePath); + // 匹配所有 {fileID: X, guid: Y, type: Z} 结构 + string pattern = @"(\{[^}]*guid:\s*(\w+)[^}]*type:\s*)3(\s*[^}]*\})"; + string newContent = Regex.Replace(content, pattern, match => { + string guid = match.Groups[2].Value; + string assetPath = AssetDatabase.GUIDToAssetPath(guid); + // 仅当资源类型为 GameObject 时修改 type + if (AssetDatabase.GetMainAssetTypeAtPath(assetPath) == typeof(GameObject)) + // if (assetPath.ToLower().EndsWith(".prefab") + ////&& assetPath.Contains("/sound/") + //&& assetPath.Contains("/level") + // ) + { + Debug.Log("已处理被引用项=>"+assetPath+" ,引用到=>"+ filePath); + Debug.Log("原值=>" + match.Value + " ,处理值=>"+ match.Groups[1].Value + "2" + match.Groups[3].Value); + //return match.Value; + return match.Groups[1].Value + "2" + match.Groups[3].Value; // type:3→2 + } + return match.Value; + }); + File.WriteAllText(filePath, newContent); + } - // 重新导入以应用更改 - textureImporter.SaveAndReimport(); - } - } } #endif \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiStatisticsCache.cs b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiStatisticsCache.cs new file mode 100644 index 00000000..f474af0e --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiStatisticsCache.cs @@ -0,0 +1,73 @@ +#if UNITY_EDITOR +using System; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + + +public class AxiStatisticsCache : ScriptableObject +{ + public List caches = new List(); +} + +[Serializable] +public class AxiStatisticsDatas +{ + /// + /// [0]Sence [1]Prefab + /// + public int type; + public string FullPath; + public List nodes = new List(); +} + +[Serializable] +public class AxiStatistics_Node +{ + public string Name; + public List link = new List(); + public int LinkHash; + public string LinkFullStr; + //public string NodeFullPath; + // /// + // /// 表示相同路径只有一个 + // /// + // public bool NodeIdxOnlyOne; + /// + /// 表示相同路径是第几个下标 + /// + //public int NodeIdx; + public List components = new List(); +} + +[Serializable] +public class AxiStatistics_Node_Link +{ + public string Name; + public bool OnlyOne; + public int Idx; + public int NodeHash; +} + +[Serializable] +public class AxiStatistics_Node_Component +{ + public string type; + /// + /// 表示相同组件只有一个 + /// + public bool ComTypeOnlyOne; + /// + /// 表示相同组件是第几个下标 + /// + public int ComIdxNum; + //Rigboody + public bool simulated; + public float gravityScale; + public bool isKinematic; + //BoxCollider2D + public Vector2 center; + public Vector2 size; +} + +#endif \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiStatisticsCache.cs.meta b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiStatisticsCache.cs.meta new file mode 100644 index 00000000..6c77510d --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/AxiProjectTools/Editors/AxiStatisticsCache.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e4cee4feffb506b4c833262e779424f6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: