完善AxiPoject工具

This commit is contained in:
sin365 2025-08-18 22:20:56 +08:00
parent ebb4cb401c
commit a1db47ab4b
7 changed files with 1230 additions and 168 deletions

View File

@ -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<Texture2D>(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

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: dc0741a79e74f96449a260406f239066

View File

@ -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<string, AxiStatisticsDatas> dictTempData = new Dictionary<string, AxiStatisticsDatas>();
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<AxiStatistics_Node_Link> nodes)
{
string hashplus = string.Empty;
foreach (var node in nodes)
{
hashplus += node.Name;
hashplus += node.Idx.ToString();
}
return hashplus.GetHashCode();
}
static string GetNodeLinkListStr(List<AxiStatistics_Node_Link> 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<AxiStatistics_Node>() };
}
AxiStatisticsDatas rootData = dictTempData[rootKey];
List<AxiStatistics_Node_Link> link = new List<AxiStatistics_Node_Link>();
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<AxiStatistics_Node_Component>();
//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<BoxCollider2D>(_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<Rigidbody2D>(_com, allcoms, comRealIdx, rig2d);
AddComponentData(_type, _rootPath, _com, nodepath, com);
}
return true;
}
/// <summary>
/// 找出同类Idx
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="allcoms"></param>
/// <param name="comRealIdx"></param>
/// <param name="com"></param>
/// <returns></returns>
static void SetCompnentIdxNum<T>(AxiStatistics_Node_Component _comData, Component[] allcoms, int comRealIdx, T com) where T : Component
{
int ComIdxNum;
bool ComTypeIsOnlyOne = false;
int TCount = com.transform.GetComponents<T>().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<BoxCollider2D>();
StatisticsCollider<Rigidbody2D>();
AxiStatisticsCache cache = ScriptableObject.CreateInstance<AxiStatisticsCache>();
foreach (var data in dictTempData)
cache.caches.Add(data.Value);
AssetDatabase.CreateAsset(cache, cachecfgPath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
public static void StatisticsCollider<T>() 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<GameObject> rootNodes = new List<GameObject>();
// 遍历场景中的所有对象
GameObject[] allObjects = FindObjectsOfType<GameObject>();
foreach (GameObject obj in allObjects)
{
// 检查对象是否有父对象
if (obj.transform.parent == null)
{
// 如果没有父对象,则它是一个根节点
rootNodes.Add(obj);
}
}
foreach (var node in rootNodes)
LoopPrefabNode<T>(0, path, path, node, 0);
}
string[] prefabGuids = AssetDatabase.FindAssets("t:Prefab");
foreach (string guid in prefabGuids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
GetPrefab<T>(path);
}
AxiProjectTools.GoTAxiProjectToolsSence();
Debug.Log("<Color=#FFF333>处理完毕 统计所有预制体和场景下的" + typeof(T).FullName + "</color>");
}
static void GetPrefab<T>(string path) where T : Component
{
#if UNITY_4_6
GameObject prefab = AssetDatabase.LoadAssetAtPath(path,typeof(GameObject)) as GameObject;
#else
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
#endif
LoopPrefabNode<T>(1, path, path, prefab.gameObject, 0);
}
static void LoopPrefabNode<T>(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<Component>();
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<T>(_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<string> errLog = new List<string>();
List<string> doneLog = new List<string>();
List<ValueTuple<string, string>> NeedRepair = new List<ValueTuple<string, string>>();
List<ValueTuple<string, string>> FinishRepair = new List<ValueTuple<string, string>>();
string CurrScenePath = string.Empty;
AxiProjectTools.GoTAxiProjectToolsSence();
#if UNITY_4_6
AxiStatisticsCache data = AssetDatabase.LoadAssetAtPath(cachecfgPath,typeof(AxiStatisticsCache)) as AxiStatisticsCache;
#else
AxiStatisticsCache data = AssetDatabase.LoadAssetAtPath<AxiStatisticsCache>(cachecfgPath);
#endif
string[] sceneGuids = AssetDatabase.FindAssets("t:scene");
List<string> ScenePath = new List<string>();
List<string> SceneName = new List<string>();
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<string> prefabPath = new List<string>();
List<string> prefabName = new List<string>();
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<string, string>($"{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<GameObject>(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<string, string>($"{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<AxiStatistics_Node_Link> linklist, out string errStr, GameObject PrefabRoot = null)
{
List<AxiStatistics_Node_Link> temp_useddlink = new List<AxiStatistics_Node_Link>();
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<int, GameObject> tempHash2Node = new Dictionary<int, GameObject>();
List<GameObject> tempGobjList = new List<GameObject>();
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<string> Errlog)
{
Errlog = new List<string>();
string err;
bool Dirty = false;
if (comdata.type == typeof(Rigidbody2D).ToString())
{
Rigidbody2D rg2d = GetCompnentById<Rigidbody2D>(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.7Rigidbody2D默认等效于新版的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<BoxCollider2D>(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<T>(GameObject gobj, AxiStatistics_Node_Component node) where T : Component
{
if (node.ComIdxNum == 0)
return gobj.GetComponent<T>();
else if (node.ComIdxNum > 0)
{
T[] coms = gobj.GetComponents<T>();
if (node.ComIdxNum < coms.Length)
return coms[node.ComIdxNum];
}
return null;
}
#endif
}
#endif

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 32aabdd304d2c4d47b8ef660f672ead1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -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<string, AxiPrefabCache_Com2GUID> ComType2GUID = new Dictionary<string, AxiPrefabCache_Com2GUID>();
static void GoTAxiProjectToolsSence()
public static string toolSenceName = "AxiProjectTools";
public static string outCsDir = Application.dataPath + "/AxiCom/";
public static Dictionary<string, AxiPrefabCache_Com2GUID> ComType2GUID = new Dictionary<string, AxiPrefabCache_Com2GUID>();
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<GameObject> rootNodes = new List<GameObject>();
// 遍历场景中的所有对象
GameObject[] allObjects = FindObjectsOfType<GameObject>();
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<AxiPrefabCache>();
foreach (var data in ComType2GUID)
cache.caches.Add(data.Value);
@ -79,66 +86,88 @@ public class AxiProjectTools : EditorWindow
GoTAxiProjectToolsSence();
Debug.Log("<Color=#FFF333>处理完毕 [1]采集所有预制体和场景下的UGUI组件</color>");
}
static void GetPrefab(string path)
{
{
#if UNITY_4_6
GameObject prefab = AssetDatabase.LoadAssetAtPath(path,typeof(GameObject)) as GameObject;
#else
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(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} | <color=#FFF333>[{monoType.Name}]</color> <color=#FF0000>{guid}</color><color=#00FF00>({monoType.FullName})</color>");
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<Component>();
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+" | <color=#FFF333>["+monoType.Name+"]</color> <color=#FF0000>"+guid+"</color><color=#00FF00>("+monoType.FullName+")</color>");
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<AxiPrefabCache>(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("<Color=#FFF333>处理完毕 [2]生成中间脚本代码</color>");
}
[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<AxiPrefabCache>(cachecfgPath);
List<MonoScript> allMonoScripts = FindAllAssetsOfType<MonoScript>();
#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("<Color=#FFF333>处理完毕 [3]收集生成的脚本</color>");
}
static List<T> FindAllAssetsOfType<T>() where T : UnityEngine.Object
{
List<T> assets = new List<T>();
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<T>(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<AxiPrefabCache>(cachecfgPath);
#endif
Dictionary<string, string> tempReplaceDict = new Dictionary<string, string>();
foreach (var data in cache.caches)
{
@ -221,7 +267,7 @@ public class AxiProjectTools : EditorWindow
AssetDatabase.Refresh();
Debug.Log("<Color=#FFF333>处理完毕 [4]替换所有预制体和场景中的组件</color>");
}
static void ProcessAllPrefabs(string form, Dictionary<string, string> tempReplaceDict, bool reverse = false)
{
List<GameObject> prefabs = new List<GameObject>();
@ -240,7 +286,7 @@ public class AxiProjectTools : EditorWindow
}
EditorUtility.ClearProgressBar();
}
/// <summary>
/// 替换值
/// </summary>
@ -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("<Color=#FFF333>处理完毕 [5]UnPack所有预制体</color>");
#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("<Color=#FFF333>处理完毕 [5]UnPack所有预制体</color>");
#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<GameObject>(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<Sprite> spritesToFix = new List<Sprite>();
[MenuItem("Axibug移植工具/ToLowVersionUnity/[6]Sprite")]
public static void FixMultipleMaterialSprites()
{
string[] guids = AssetDatabase.FindAssets("t:sprite");
List<Sprite> spritesToFix = new List<Sprite>();
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path);
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(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("<Color=#FFF333>处理完毕 [6]修复Sprite</color>");
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("<Color=#FFF333>处理完毕 [6]修复Sprite</color>");
}
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("<Color=#FFF333>处理完毕 [5]导入低版本后:修复预制体依赖丢失</color>");
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

View File

@ -0,0 +1,73 @@
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class AxiStatisticsCache : ScriptableObject
{
public List<AxiStatisticsDatas> caches = new List<AxiStatisticsDatas>();
}
[Serializable]
public class AxiStatisticsDatas
{
/// <summary>
/// [0]Sence [1]Prefab
/// </summary>
public int type;
public string FullPath;
public List<AxiStatistics_Node> nodes = new List<AxiStatistics_Node>();
}
[Serializable]
public class AxiStatistics_Node
{
public string Name;
public List<AxiStatistics_Node_Link> link = new List<AxiStatistics_Node_Link>();
public int LinkHash;
public string LinkFullStr;
//public string NodeFullPath;
// /// <summary>
// /// 表示相同路径只有一个
// /// </summary>
// public bool NodeIdxOnlyOne;
/// <summary>
/// 表示相同路径是第几个下标
/// </summary>
//public int NodeIdx;
public List<AxiStatistics_Node_Component> components = new List<AxiStatistics_Node_Component>();
}
[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;
/// <summary>
/// 表示相同组件只有一个
/// </summary>
public bool ComTypeOnlyOne;
/// <summary>
/// 表示相同组件是第几个下标
/// </summary>
public int ComIdxNum;
//Rigboody
public bool simulated;
public float gravityScale;
public bool isKinematic;
//BoxCollider2D
public Vector2 center;
public Vector2 size;
}
#endif

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e4cee4feffb506b4c833262e779424f6
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData: