From 18563783773aa59f269d29f4f5f9970845f62585 Mon Sep 17 00:00:00 2001 From: VaDiM Date: Sat, 28 Feb 2026 12:20:05 +0300 Subject: [PATCH] Add support for Unity 6.5 --- AssetStudio/ClassIDType.cs | 29 +++++- AssetStudio/Classes/AnimationClip.cs | 5 + AssetStudio/Classes/AnimatorController.cs | 13 ++- AssetStudio/Classes/Sprite.cs | 8 +- AssetStudio/Classes/SpriteAtlas.cs | 12 ++- .../Extensions/BinaryReaderExtensions.cs | 12 +++ AssetStudio/ObjectReader.cs | 5 + AssetStudio/SerializedFile.cs | 99 ++++++++++++++++--- AssetStudio/SerializedFileFormatVersion.cs | 16 ++- 9 files changed, 167 insertions(+), 32 deletions(-) diff --git a/AssetStudio/ClassIDType.cs b/AssetStudio/ClassIDType.cs index 234adeb..fc6f25b 100644 --- a/AssetStudio/ClassIDType.cs +++ b/AssetStudio/ClassIDType.cs @@ -1,4 +1,4 @@ -// official Class ID Reference: https://docs.unity3d.com/Manual/ClassIDReference.html +// official Class ID Reference: https://docs.unity3d.com/Manual/ClassIDReference.html namespace AssetStudio { public enum ClassIDType @@ -38,6 +38,7 @@ namespace AssetStudio TextAsset = 49, Rigidbody2D = 50, Physics2DManager = 51, + NotificationManager = 52, Collider2D = 53, Rigidbody = 54, PhysicsManager = 55, @@ -52,7 +53,9 @@ namespace AssetStudio BoxCollider = 65, CompositeCollider2D = 66, EdgeCollider2D = 68, + PolygonColliderBase2D = 69, CapsuleCollider2D = 70, + AnimationManager = 71, ComputeShader = 72, AnimationClip = 74, ConstantForce = 75, @@ -92,7 +95,7 @@ namespace AssetStudio LensFlare = 123, FlareLayer = 124, HaloLayer = 125, - NavMeshAreas = 126, + //NavMeshAreas = 126, NavMeshProjectSettings = 126, HaloManager = 127, Font = 128, @@ -101,7 +104,7 @@ namespace AssetStudio GUITexture = 131, GUIText = 132, GUIElement = 133, - PhysicMaterial = 134, + PhysicsMaterial = 134, SphereCollider = 135, CapsuleCollider = 136, SkinnedMeshRenderer = 137, @@ -214,6 +217,7 @@ namespace AssetStudio UnityAdsManager = 292, RuntimeInitializeOnLoadManager = 300, CloudWebServicesManager = 301, + CloudServiceHandlerBehaviour = 302, UnityAnalyticsManager = 303, CrashReportManager = 304, PerformanceReportingManager = 305, @@ -227,6 +231,7 @@ namespace AssetStudio WorldAnchor = 362, OcclusionCullingData = 363, //kLargestRuntimeClassID = 364 + MarshallingTestObject = 900, SmallestEditorClassID = 1000, PrefabInstance = 1001, EditorExtensionImpl = 1002, @@ -236,6 +241,8 @@ namespace AssetStudio TextureImporter = 1006, ShaderImporter = 1007, ComputeShaderImporter = 1008, + AvatarBodyMask = 1011, + AvatarSkeletonMask = 1012, AudioImporter = 1020, HierarchyState = 1026, GUIDSerializer = 1027, @@ -280,6 +287,7 @@ namespace AssetStudio BuildReport = 1125, PackedAssets = 1126, VideoClipImporter = 1127, + StyleSheetImporter = 1128, ActivationLogComponent = 2000, //kLargestEditorClassID = 2001 //kClassIdOutOfHierarchy = 100000 @@ -303,17 +311,21 @@ namespace AssetStudio Grid = 156049354, ScenesUsingAssets = 156483287, ArticulationBody = 171741748, + PhysicsCoreProjectSettings2D = 176606843, Preset = 181963792, + ShaderIncludeReflection = 209234237, EmptyObject = 277625683, IConstraint = 285090594, TestObjectWithSpecialLayoutOne = 293259124, AssemblyDefinitionReferenceImporter = 294290339, SiblingDerived = 334799969, TestObjectWithSerializedMapStringNonAlignedStruct = 342846651, + ContentSummary = 330615474, AudioResource = 355983997, SubDerived = 367388927, AssetImportInProgressProxy = 369655926, PluginBuildInfo = 382020655, + UIAnimationBinder = 382093023, MemorySettings = 387306366, BuildMetaDataImporter = 403037116, BuildInstructionImporter = 403037117, @@ -332,6 +344,8 @@ namespace AssetStudio AssemblyDefinitionReferenceAsset = 662584278, BuiltAssetBundleInfoSet = 668709126, SpriteAtlas = 687078895, + BlobObject = 687930938, + DifferentMarshallingTestObject = 702665669, RayTracingShaderImporter = 747330370, BuildArchiveImporter = 780535461, PreviewImporter = 815301076, @@ -349,8 +363,13 @@ namespace AssetStudio VisualEffectSubgraphBlock = 994735404, LocalizationImporter = 1027052791, Derived = 1091556383, + BlockShaderSyntaxTree = 1096314112, + BlockShaderContainer = 1096314113, + BlockShaderErrors = 1096314114, PropertyModificationsTargetTestObject = 1111377672, ReferencesArtifactGenerator = 1114811875, + RenderAs2D = 1120581460, + BlockShaderSourceArtifact = 1149764431, AssemblyDefinitionAsset = 1152215463, SceneVisibilityState = 1154873562, LookAtConstraint = 1183024399, @@ -382,6 +401,7 @@ namespace AssetStudio ParentConstraint = 1773428102, FakeComponent = 1803986026, RuleSetFileImporter = 1777034230, + D3D12DeviceFilterLists = 1798438448, PositionConstraint = 1818360608, RotationConstraint = 1818360609, ScaleConstraint = 1818360610, @@ -390,6 +410,7 @@ namespace AssetStudio PackageManifestImporter = 1896753126, RoslynAnalyzerConfigImporter = 1903396204, UIRenderer = 1931382933, + PanelRenderer = 1931382934, TerrainLayer = 1953259897, SpriteShapeRenderer = 1971053207, NativeObjectType = 1977754360, @@ -402,6 +423,8 @@ namespace AssetStudio VisualEffect = 2083052967, LocalizationAsset = 2083778819, ScriptedImporter = 2089858483, + BlockShaderImporter = 2097406814, ShaderIncludeImporter = 2103361453, + TilemapEditorUserSettings = 2126867596, } } diff --git a/AssetStudio/Classes/AnimationClip.cs b/AssetStudio/Classes/AnimationClip.cs index 1558218..b1998e6 100644 --- a/AssetStudio/Classes/AnimationClip.cs +++ b/AssetStudio/Classes/AnimationClip.cs @@ -926,6 +926,7 @@ namespace AssetStudio public byte isPPtrCurve; public byte isIntCurve; public byte isSerializeReferenceCurve; + public ushort metaData; public GenericBinding() { } @@ -953,6 +954,10 @@ namespace AssetStudio { isSerializeReferenceCurve = reader.ReadByte(); } + if ((!version.IsAlpha && version >= (6000, 5)) || (version.IsAlpha && version >= (6000, 5, 0, 7))) //6000.5.0a7 and up + { + metaData = reader.ReadUInt16(); + } reader.AlignStream(); } } diff --git a/AssetStudio/Classes/AnimatorController.cs b/AssetStudio/Classes/AnimatorController.cs index 0afb4e9..095e2e0 100644 --- a/AssetStudio/Classes/AnimatorController.cs +++ b/AssetStudio/Classes/AnimatorController.cs @@ -497,7 +497,13 @@ namespace AssetStudio } m_DefaultState = reader.ReadUInt32(); - m_MotionSetCount = reader.ReadUInt32(); + m_MotionSetCount = reader.ReadUInt32(); //m_SynchronizedLayerCount from 2018.2 + + if (version >= (6000, 4)) + { + var m_EvaluateTransitionsOnStart = reader.ReadBoolean(); + reader.AlignStream(); + } } } @@ -604,6 +610,11 @@ namespace AssetStudio public AnimatorController(ObjectReader reader) : base(reader) { + if (reader.version >= (6000, 4)) + { + var m_EvaluateTransitionsOnStart = reader.ReadBoolean(); + reader.AlignStream(); + } var m_ControllerSize = reader.ReadUInt32(); var m_Controller = new ControllerConstant(reader); diff --git a/AssetStudio/Classes/Sprite.cs b/AssetStudio/Classes/Sprite.cs index 8358bed..083a602 100644 --- a/AssetStudio/Classes/Sprite.cs +++ b/AssetStudio/Classes/Sprite.cs @@ -87,6 +87,7 @@ namespace AssetStudio public ushort[] indices; public Matrix4x4[] m_Bindpose; public BoneWeights4[] m_SourceSkin; + public BlendShapeData m_BlendShapes; public Rectf textureRect; public Vector2 textureRectOffset; public Vector2 atlasRectOffset; @@ -154,6 +155,11 @@ namespace AssetStudio } } + if ((!version.IsAlpha && version >= (6000, 5)) || (version.IsAlpha && version >= (6000, 5, 0, 7))) //6000.5.0a7 and up + { + m_BlendShapes = new BlendShapeData(reader); + } + textureRect = new Rectf(reader); textureRectOffset = reader.ReadVector2(); if (version >= (5, 6)) //5.6 and up @@ -222,7 +228,7 @@ namespace AssetStudio } m_Extrude = reader.ReadUInt32(); - if (version >= (5, 3)) //5.3 and up + if (version.IsInRange((5, 3), (6000, 5))) //5.3 - 6000.4 { m_IsPolygon = reader.ReadBoolean(); reader.AlignStream(); diff --git a/AssetStudio/Classes/SpriteAtlas.cs b/AssetStudio/Classes/SpriteAtlas.cs index a9c45f0..4e6eefd 100644 --- a/AssetStudio/Classes/SpriteAtlas.cs +++ b/AssetStudio/Classes/SpriteAtlas.cs @@ -46,9 +46,12 @@ namespace AssetStudio public sealed class SpriteAtlas : NamedObject { public List> m_PackedSprites; + public string[] m_PackedSpriteNamesToIndex; [JsonConverter(typeof(JsonConverterHelper.RenderDataMapConverter))] public Dictionary, SpriteAtlasData> m_RenderDataMap; + public string m_Tag; public bool m_IsVariant; + public Guid m_Guid; public SpriteAtlas(ObjectReader reader) : base(reader) { @@ -59,7 +62,7 @@ namespace AssetStudio m_PackedSprites.Add(new PPtr(reader)); } - var m_PackedSpriteNamesToIndex = reader.ReadStringArray(); + m_PackedSpriteNamesToIndex = reader.ReadStringArray(); var m_RenderDataMapSize = reader.ReadInt32(); m_RenderDataMap = new Dictionary, SpriteAtlasData>(); @@ -70,9 +73,14 @@ namespace AssetStudio var value = new SpriteAtlasData(reader); m_RenderDataMap.Add(new KeyValuePair(first, second), value); } - var m_Tag = reader.ReadAlignedString(); + m_Tag = reader.ReadAlignedString(); m_IsVariant = reader.ReadBoolean(); reader.AlignStream(); + + if ((!version.IsAlpha && version >= (6000, 5)) || (version.IsAlpha && version >= (6000, 5, 0, 4))) //6000.5.0a4 and up + { + m_Guid = new Guid(reader.ReadBytes(16)); + } } } } diff --git a/AssetStudio/Extensions/BinaryReaderExtensions.cs b/AssetStudio/Extensions/BinaryReaderExtensions.cs index 2490754..af79693 100644 --- a/AssetStudio/Extensions/BinaryReaderExtensions.cs +++ b/AssetStudio/Extensions/BinaryReaderExtensions.cs @@ -75,6 +75,18 @@ namespace AssetStudio return Encoding.Unicode.GetString(bytes.ToArray()); } + public static string ReadBytesAsHexString(this BinaryReader reader, int length) + { +#if NETFRAMEWORK + var bytes = reader.ReadBytes(length); + return BitConverter.ToString(bytes).Replace("-", string.Empty); +#else + Span bytes = length < 256 ? stackalloc byte[length] : new byte[length]; + _ = reader.Read(bytes); + return Convert.ToHexString(bytes); +#endif + } + public static Quaternion ReadQuaternion(this BinaryReader reader) { return new Quaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); diff --git a/AssetStudio/ObjectReader.cs b/AssetStudio/ObjectReader.cs index 3c1b9f0..04e5922 100644 --- a/AssetStudio/ObjectReader.cs +++ b/AssetStudio/ObjectReader.cs @@ -37,6 +37,11 @@ namespace AssetStudio serializedType = objectInfo.serializedType; platform = assetsFile.m_TargetPlatform; m_Version = assetsFile.header.m_Version; + + if (assetsFile.ExtractedTypeTreeHashes.Count > 0) + { + assetsFile.ReadExtractedTypeTree(); + } } public void ThrowIfTooLarge(float val) diff --git a/AssetStudio/SerializedFile.cs b/AssetStudio/SerializedFile.cs index 4b05291..ea9b6bd 100644 --- a/AssetStudio/SerializedFile.cs +++ b/AssetStudio/SerializedFile.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; namespace AssetStudio { @@ -12,8 +13,9 @@ namespace AssetStudio public string originalPath; public string fileName; public UnityVersion version = new UnityVersion(); - public List Objects; - public Dictionary ObjectsDic; + public readonly List Objects; + public readonly Dictionary ObjectsDic; + public readonly Dictionary ExtractedTypeTreeHashes = new Dictionary(); public SerializedFileHeader header; private byte m_FileEndianess; @@ -270,7 +272,21 @@ namespace AssetStudio { type.m_Type = new TypeTree(); type.m_Type.m_Nodes = new List(); - if (header.m_Version >= SerializedFileFormatVersion.Unknown_12 || header.m_Version == SerializedFileFormatVersion.Unknown_10) + if (header.m_Version >= SerializedFileFormatVersion.ExtractedTypeTreeSupport) + { + var typeTreeHash = reader.ReadBytesAsHexString(16); //xxh3 + var typeTreeSize = reader.ReadInt32(); + if (typeTreeSize != 0) + { + TypeTreeBlobRead(type.m_Type); + } + else + { + type.m_Type = null; + ExtractedTypeTreeHashes.Add(typeTreeHash, type); + } + } + else if (header.m_Version >= SerializedFileFormatVersion.Unknown_12 || header.m_Version == SerializedFileFormatVersion.Unknown_10) { TypeTreeBlobRead(type.m_Type); } @@ -326,28 +342,33 @@ namespace AssetStudio } } - private void TypeTreeBlobRead(TypeTree m_Type) + private void TypeTreeBlobRead(TypeTree m_Type, FileReader fileReader = null) { - int numberOfNodes = reader.ReadInt32(); - int stringBufferSize = reader.ReadInt32(); + var typeTreeReader = fileReader ?? reader; + if (header.m_Version >= SerializedFileFormatVersion.ExtractedTypeTreeSupport) + { + ReadTypeTreeHeader(typeTreeReader); + } + int numberOfNodes = typeTreeReader.ReadInt32(); + int stringBufferSize = typeTreeReader.ReadInt32(); for (var i = 0; i < numberOfNodes; i++) { var typeTreeNode = new TypeTreeNode(); m_Type.m_Nodes.Add(typeTreeNode); - typeTreeNode.m_Version = reader.ReadUInt16(); - typeTreeNode.m_Level = reader.ReadByte(); - typeTreeNode.m_TypeFlags = reader.ReadByte(); - typeTreeNode.m_TypeStrOffset = reader.ReadUInt32(); - typeTreeNode.m_NameStrOffset = reader.ReadUInt32(); - typeTreeNode.m_ByteSize = reader.ReadInt32(); - typeTreeNode.m_Index = reader.ReadInt32(); - typeTreeNode.m_MetaFlag = reader.ReadInt32(); + typeTreeNode.m_Version = typeTreeReader.ReadUInt16(); + typeTreeNode.m_Level = typeTreeReader.ReadByte(); + typeTreeNode.m_TypeFlags = typeTreeReader.ReadByte(); + typeTreeNode.m_TypeStrOffset = typeTreeReader.ReadUInt32(); + typeTreeNode.m_NameStrOffset = typeTreeReader.ReadUInt32(); + typeTreeNode.m_ByteSize = typeTreeReader.ReadInt32(); + typeTreeNode.m_Index = typeTreeReader.ReadInt32(); + typeTreeNode.m_MetaFlag = typeTreeReader.ReadInt32(); if (header.m_Version >= SerializedFileFormatVersion.TypeTreeNodeWithTypeFlags) { - typeTreeNode.m_RefTypeHash = reader.ReadUInt64(); + typeTreeNode.m_RefTypeHash = typeTreeReader.ReadUInt64(); } } - m_Type.m_StringBuffer = reader.ReadBytes(stringBufferSize); + m_Type.m_StringBuffer = typeTreeReader.ReadBytes(stringBufferSize); var stringBufferSpan = new ReadOnlySpan(m_Type.m_StringBuffer); foreach (var m_Node in m_Type.m_Nodes) @@ -372,6 +393,52 @@ namespace AssetStudio } } + private void ReadTypeTreeHeader(FileReader typeTreeReader) + { + var typeTreeSign = typeTreeReader.ReadInt32(); //0x7474686d ("tthm") + var serializedFileVersion = (SerializedFileFormatVersion)typeTreeReader.ReadInt32(); + + if (typeTreeSign != 0x7474686d) + { + Logger.Warning("Unknown TypeTree file format"); + } + + if (serializedFileVersion != header.m_Version) + { + Logger.Warning("Serialized file versions do not match"); + } + } + + public void ReadExtractedTypeTree() + { + foreach (var kv in ExtractedTypeTreeHashes) + { + if (assetsManager.resourceFileReaders.TryGetValue(kv.Key, out var binaryReader)) + { + var fileReader = (FileReader)binaryReader; + fileReader.Endian = EndianType.LittleEndian; + fileReader.Position = 0; + + kv.Value.m_Type = new TypeTree(); + kv.Value.m_Type.m_Nodes = new List(); + TypeTreeBlobRead(kv.Value.m_Type, fileReader); + + ExtractedTypeTreeHashes[kv.Key] = null; + } + } + var notFound = ExtractedTypeTreeHashes.Where(x=> x.Value != null).ToArray(); + if (notFound.Length > 0 && notFound.Length != ExtractedTypeTreeHashes.Count) + { + foreach (var kv in notFound) + { + Logger.Warning($"Failed to find extracted typetree with hash \"{kv.Key}\" for \"{(ClassIDType)kv.Value.classID}\" asset type"); + } + Logger.Warning("Not all typetree hashes were found in the loaded typetree file\n" + + "The typetree file is probably outdated or not designed for the loaded asset bundles"); + } + ExtractedTypeTreeHashes.Clear(); + } + public void AddObject(Object obj) { Objects.Add(obj); diff --git a/AssetStudio/SerializedFileFormatVersion.cs b/AssetStudio/SerializedFileFormatVersion.cs index fc853b8..5ecf510 100644 --- a/AssetStudio/SerializedFileFormatVersion.cs +++ b/AssetStudio/SerializedFileFormatVersion.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace AssetStudio +namespace AssetStudio { public enum SerializedFileFormatVersion { @@ -80,8 +74,12 @@ namespace AssetStudio /// StoresTypeDependencies = 21, /// - /// 2020.1 to x + /// 2020.1 to 6000.5 /// - LargeFilesSupport = 22 + LargeFilesSupport = 22, + /// + /// 6000.5.0a5 to x + /// + ExtractedTypeTreeSupport = 23, } }