From fbfdb789f5b9c140d25be4094f772354c2ee05e1 Mon Sep 17 00:00:00 2001 From: Perfare Date: Sun, 15 Jan 2017 23:20:40 +0800 Subject: [PATCH] support export MonoBehaviour --- Unity Studio/AssetsFile.cs | 2 +- Unity Studio/EndianStream.cs | 2 +- Unity Studio/Unity Classes/GameObject.cs | 5 +- Unity Studio/Unity Classes/MonoBehaviour.cs | 166 ++++++++++++++++++++ Unity Studio/Unity Classes/Shader.cs | 1 - Unity Studio/Unity Studio.csproj | 1 + Unity Studio/UnityStudioForm.cs | 49 ++++-- 7 files changed, 205 insertions(+), 21 deletions(-) create mode 100644 Unity Studio/Unity Classes/MonoBehaviour.cs diff --git a/Unity Studio/AssetsFile.cs b/Unity Studio/AssetsFile.cs index 5825aa7..6c90578 100644 --- a/Unity Studio/AssetsFile.cs +++ b/Unity Studio/AssetsFile.cs @@ -340,7 +340,7 @@ namespace Unity_Studio baseStrings[894] = "TypelessData"; baseStrings[907] = "UInt16"; baseStrings[928] = "UInt8"; - baseStrings[934] = "unsigned int"; + baseStrings[934] = "UInt"; baseStrings[981] = "vector"; baseStrings[988] = "Vector2f"; baseStrings[997] = "Vector3f"; diff --git a/Unity Studio/EndianStream.cs b/Unity Studio/EndianStream.cs index c29dba8..1799d88 100644 --- a/Unity Studio/EndianStream.cs +++ b/Unity Studio/EndianStream.cs @@ -167,7 +167,7 @@ namespace Unity_Studio { byte[] stringData = new byte[length]; base.Read(stringData, 0, length); - var result = System.Text.Encoding.UTF8.GetString(stringData); //must verify strange characters in PS3 + var result = Encoding.UTF8.GetString(stringData); //must verify strange characters in PS3 /*string result = ""; char c; diff --git a/Unity Studio/Unity Classes/GameObject.cs b/Unity Studio/Unity Classes/GameObject.cs index 068ff7d..c9cab78 100644 --- a/Unity Studio/Unity Classes/GameObject.cs +++ b/Unity Studio/Unity Classes/GameObject.cs @@ -16,7 +16,7 @@ namespace Unity_Studio public string m_Name; public ushort m_Tag; public bool m_IsActive; - + public string uniqueID = "0";//this way file and folder TreeNodes will be treated as FBX scene public GameObject(AssetPreloadData preloadData) @@ -56,6 +56,7 @@ namespace Unity_Studio m_SkinnedMeshRenderer = sourceFile.ReadPPtr(); break; default: + a_Stream.Position -= 4; PPtr m_Component = sourceFile.ReadPPtr(); break; } @@ -67,7 +68,7 @@ namespace Unity_Studio if (m_Name == "") { m_Name = "GameObject #" + uniqueID; } m_Tag = a_Stream.ReadUInt16(); m_IsActive = a_Stream.ReadBoolean(); - + base.Text = m_Name; preloadData.Text = m_Name; //name should be unique diff --git a/Unity Studio/Unity Classes/MonoBehaviour.cs b/Unity Studio/Unity Classes/MonoBehaviour.cs new file mode 100644 index 0000000..aa2373b --- /dev/null +++ b/Unity Studio/Unity Classes/MonoBehaviour.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Unity_Studio +{ + class MonoBehaviour + { + public string serializedText; + + public MonoBehaviour(AssetPreloadData preloadData, bool readSwitch) + { + var sourceFile = preloadData.sourceFile; + var a_Stream = preloadData.sourceFile.a_Stream; + a_Stream.Position = preloadData.Offset; + + var m_GameObject = sourceFile.ReadPPtr(); + var m_Enabled = a_Stream.ReadByte(); + a_Stream.AlignStream(4); + var m_Script = sourceFile.ReadPPtr(); + var m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); + if (readSwitch) + { + preloadData.extension = ".txt"; + a_Stream.Position = preloadData.Offset; + ClassStrStruct classStructure; + if (sourceFile.ClassStructures.TryGetValue(preloadData.Type1, out classStructure)) + { + var member = classStructure.members; + var strs = member.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); + var sb = new StringBuilder(); + Read(sb, strs, a_Stream); + serializedText = sb.ToString(); + } + else + { + var str = "PPtr m_GameObject\r\n"; + str += "\tint m_FileID = " + m_GameObject.m_FileID + "\r\n"; + str += "\tint64 m_PathID = " + m_GameObject.m_PathID + "\r\n"; + str += "UInt8 m_Enabled = " + m_Enabled + "\r\n"; + str += "PPtr m_Script\r\n"; + str += "\tint m_FileID = " + m_Script.m_FileID + "\r\n"; + str += "\tint64 m_PathID = " + m_Script.m_PathID + "\r\n"; + str += "string m_Name = \"" + m_Name + "\"\r\n"; + serializedText = str; + } + } + else + { + if (m_Name != "") + { + preloadData.Text = m_Name; + } + else + { + preloadData.Text = preloadData.TypeString + " #" + preloadData.uniqueID; + } + preloadData.SubItems.AddRange(new string[] { preloadData.TypeString, preloadData.Size.ToString() }); + } + } + + private void Read(StringBuilder sb, string[] strs, EndianStream a_Stream) + { + for (int i = 0; i < strs.Length; i++) + { + var strs2 = strs[i].Split(' '); + var str = strs2[0].Split('\t'); + var level = str.Length - 1; + var varTypeStr = str.Last(); + var varNameStr = strs2[1]; + if (varTypeStr == "int") + { + var value = a_Stream.ReadInt32(); + sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); + a_Stream.AlignStream(4); + } + else if (varTypeStr == "UInt") + { + var value = a_Stream.ReadUInt32(); + sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); + a_Stream.AlignStream(4); + } + else if (varTypeStr == "int64") + { + var value = a_Stream.ReadInt64(); + sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); + a_Stream.AlignStream(4); + } + else if (varTypeStr == "UInt16") + { + var value = a_Stream.ReadUInt16(); + sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); + a_Stream.AlignStream(4); + } + else if (varTypeStr == "SInt16") + { + var value = a_Stream.ReadInt16(); + sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); + a_Stream.AlignStream(4); + } + else if (varTypeStr == "UInt8") + { + var value = a_Stream.ReadByte(); + sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); + a_Stream.AlignStream(4); + } + else if (varTypeStr == "float") + { + var value = a_Stream.ReadSingle(); + sb.AppendFormat("{0}{1} {2} = {3:f}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); + a_Stream.AlignStream(4); + } + else if (varTypeStr == "bool") + { + var value = a_Stream.ReadBoolean(); + sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); + a_Stream.AlignStream(4); + } + else if (varTypeStr == "string") + { + var value = a_Stream.ReadAlignedString(a_Stream.ReadInt32()); + sb.AppendFormat("{0}{1} {2} = \"{3}\"\r\n", (new string('\t', level)), varTypeStr, varNameStr, value); + i += 3;//skip + } + else if (varTypeStr == "Array") + { + sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); + var size = a_Stream.ReadInt32(); + sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), "int", "size", size); + var array = ReadArray(strs, level, i); + for (int j = 0; j < size; j++) + { + sb.AppendFormat("{0}[{1}]\r\n", (new string('\t', level + 1)), j); + Read(sb, array, a_Stream); + } + i += array.Length + 1;//skip + } + else + { + sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr); + } + } + } + + private string[] ReadArray(string[] strs, int level, int index) + { + List strs3 = new List(); + for (int i = index + 2; i < strs.Length; i++)//skip int size + { + var strs2 = strs[i].Split(' '); + var str = strs2[0].Split('\t'); + var level2 = str.Length - 1; + if (level2 <= level) + { + return strs3.ToArray(); + } + else + { + strs3.Add(strs[i]); + } + } + return strs3.ToArray(); + } + } +} diff --git a/Unity Studio/Unity Classes/Shader.cs b/Unity Studio/Unity Classes/Shader.cs index d7f2691..a273241 100644 --- a/Unity Studio/Unity Classes/Shader.cs +++ b/Unity Studio/Unity Classes/Shader.cs @@ -34,7 +34,6 @@ namespace Unity_Studio if (m_Name != "") { preloadData.Text = m_Name; } else { preloadData.Text = preloadData.TypeString + " #" + preloadData.uniqueID; } preloadData.SubItems.AddRange(new string[] { preloadData.TypeString, preloadData.exportSize.ToString() }); - } } else diff --git a/Unity Studio/Unity Studio.csproj b/Unity Studio/Unity Studio.csproj index b4dcadf..3e28cb1 100644 --- a/Unity Studio/Unity Studio.csproj +++ b/Unity Studio/Unity Studio.csproj @@ -171,6 +171,7 @@ + diff --git a/Unity Studio/UnityStudioForm.cs b/Unity Studio/UnityStudioForm.cs index 692a7d2..8deef4c 100644 --- a/Unity Studio/UnityStudioForm.cs +++ b/Unity Studio/UnityStudioForm.cs @@ -569,6 +569,7 @@ namespace Unity_Studio break; case 48: case 49: + case 114: textPreviewBox.Visible = !textPreviewBox.Visible; break; case 128: @@ -701,7 +702,7 @@ namespace Unity_Studio } case 48: //Shader { - Shader m_TextAsset = new Shader(asset, false); + Shader m_Shader = new Shader(asset, false); exportable = true; break; } @@ -717,7 +718,13 @@ namespace Unity_Studio exportable = true; break; } - //case 89: //CubeMap + case 114: //MonoBehaviour + { + var m_MonoBehaviour = new MonoBehaviour(asset, false); + if (asset.Type1 != asset.Type2 && assetsFile.ClassStructures.ContainsKey(asset.Type1)) + exportable = true; + break; + } case 128: //Font { unityFont m_Font = new unityFont(asset, false); @@ -730,19 +737,6 @@ namespace Unity_Studio productName = plSet.productName; break; } - case 114: //MonoBehaviour - { - if (asset.Offset + 0x1c + 4 > asset.sourceFile.a_Stream.BaseStream.Length) - break; - asset.sourceFile.a_Stream.Position = asset.Offset + 0x1c; - var len = asset.sourceFile.a_Stream.ReadInt32(); - if (len > 0 && len < asset.Size - 4 - 0x1c) - { - var bytes = asset.sourceFile.a_Stream.ReadBytes(len); - asset.Text = Encoding.UTF8.GetString(bytes); - } - break; - } case 21: //Material case 43: //Mesh case 74: //AnimationClip @@ -1315,6 +1309,16 @@ namespace Unity_Studio break; } #endregion + #region MonoBehaviour + case 114: + { + MonoBehaviour m_MonoBehaviour = new MonoBehaviour(asset, true); + textPreviewBox.Text = m_MonoBehaviour.serializedText; + textPreviewBox.Visible = true; + + break; + } + #endregion #region Font case 128: //Font { @@ -3144,7 +3148,7 @@ namespace Unity_Studio } break; case 48: - if (!ExportFileExists(exportpath + asset.Text + ".txt", asset.TypeString)) + if (!ExportFileExists(exportpath + asset.Text + asset.extension, asset.TypeString)) { ExportShader(new Shader(asset, true), exportpath + asset.Text + ".txt"); exportedCount++; @@ -3158,6 +3162,14 @@ namespace Unity_Studio exportedCount++; } break; + case 114: + MonoBehaviour m_MonoBehaviour = new MonoBehaviour(asset, true); + if (!ExportFileExists(exportpath + asset.Text + asset.extension, asset.TypeString)) + { + ExportMonoBehaviour(m_MonoBehaviour, exportpath + asset.Text + asset.extension); + exportedCount++; + } + break; case 128: unityFont m_Font = new unityFont(asset, true); if (!ExportFileExists(exportpath + asset.Text + asset.extension, asset.TypeString)) @@ -3395,6 +3407,11 @@ namespace Unity_Studio return true; } + private void ExportMonoBehaviour(MonoBehaviour m_MonoBehaviour, string exportFilename) + { + File.WriteAllText(exportFilename, m_MonoBehaviour.serializedText); + } + private void ExportShader(Shader m_Shader, string exportFilename) { File.WriteAllBytes(exportFilename, m_Shader.m_Script);