5252 "Vector3" : "Vector3f" ,
5353 "Vector4" : "Vector4f" ,
5454 "Quaternion" : "Quaternionf" ,
55- "Object" : "object" ,
56- "Array" : "list" ,
55+ "Object" : "object" ,
5756 "Type" : "type" ,
5857 "MethodInfo" : "object" ,
5958 "PropertyInfo" : "object" ,
6059}
61-
60+ Typetree_MonoBehaviour = [
61+ {
62+ "m_Type" : "MonoBehaviour" ,
63+ "m_Name" : "Base" ,
64+ "m_MetaFlag" : 0 ,
65+ "m_Level" : 0
66+ },
67+ {
68+ "m_Type" : "PPtr<GameObject>" ,
69+ "m_Name" : "m_GameObject" ,
70+ "m_MetaFlag" : 0 ,
71+ "m_Level" : 1
72+ },
73+ {
74+ "m_Type" : "int" ,
75+ "m_Name" : "m_FileID" ,
76+ "m_MetaFlag" : 0 ,
77+ "m_Level" : 2
78+ },
79+ {
80+ "m_Type" : "SInt64" ,
81+ "m_Name" : "m_PathID" ,
82+ "m_MetaFlag" : 0 ,
83+ "m_Level" : 2
84+ },
85+ {
86+ "m_Type" : "UInt8" ,
87+ "m_Name" : "m_Enabled" ,
88+ "m_MetaFlag" : 16384 ,
89+ "m_Level" : 1
90+ },
91+ {
92+ "m_Type" : "PPtr<MonoScript>" ,
93+ "m_Name" : "m_Script" ,
94+ "m_MetaFlag" : 0 ,
95+ "m_Level" : 1
96+ },
97+ {
98+ "m_Type" : "int" ,
99+ "m_Name" : "m_FileID" ,
100+ "m_MetaFlag" : 0 ,
101+ "m_Level" : 2
102+ },
103+ {
104+ "m_Type" : "SInt64" ,
105+ "m_Name" : "m_PathID" ,
106+ "m_MetaFlag" : 0 ,
107+ "m_Level" : 2
108+ },
109+ {
110+ "m_Type" : "string" ,
111+ "m_Name" : "m_Name" ,
112+ "m_MetaFlag" : 0 ,
113+ "m_Level" : 1
114+ },
115+ {
116+ "m_Type" : "Array" ,
117+ "m_Name" : "Array" ,
118+ "m_MetaFlag" : 16384 ,
119+ "m_Level" : 2
120+ },
121+ {
122+ "m_Type" : "int" ,
123+ "m_Name" : "size" ,
124+ "m_MetaFlag" : 0 ,
125+ "m_Level" : 3
126+ },
127+ {
128+ "m_Type" : "char" ,
129+ "m_Name" : "data" ,
130+ "m_MetaFlag" : 0 ,
131+ "m_Level" : 3
132+ }
133+ ]
62134# XXX: Can't use attrs here since subclassing MonoBehavior and such - though defined by the typetree dump
63135# seem to be only valid if the class isn't a property of another class
64136# In which case the MonoBehavior attributes are inherited by the parent class and does not
72144 "from UnityPy.files.ObjectReader import ObjectReader" ,
73145 "from UnityPy.classes import *" ,
74146 "from UnityPy.classes.math import (ColorRGBA, Matrix3x4f, Matrix4x4f, Quaternionf, Vector2f, Vector3f, Vector4f, float3, float4,)" ,
75- '''
147+ '''
76148UTTCG_Classes = dict()
77- def UTTCGen(fullname: str, typetree: dict):
149+ def UTTCGen(fullname: str, typetree: List[ dict] ):
78150 """dataclass-like decorator for typetree classess with nested type support
79151
80152 limitations:
@@ -109,7 +181,17 @@ def reduce_init(clazz, **d):
109181 if hasattr(sub, "__origin__") and sub.__origin__ is not None:
110182 sub = sub.__origin__
111183 if isinstance(d[k], dict):
112- setattr(self, k, sub(**d[k]))
184+ # Special cases
185+ # Color with `rgba` field
186+ if sub == ColorRGBA and 'rgba' in d[k]:
187+ rgba = d[k]['rgba']
188+ r = ((rgba >> 24) & 0xFF) / 255
189+ g = ((rgba >> 16) & 0xFF) / 255
190+ b = ((rgba >> 8) & 0xFF) / 255
191+ a = (rgba & 0xFF) / 255
192+ setattr(self, k, sub(r, g, b, a))
193+ else:
194+ setattr(self, k, sub(**d[k]))
113195 else:
114196 setattr(self, k, sub(d[k]))
115197 def reduce_base(clazz, **d):
@@ -128,7 +210,7 @@ def __repr__(self) -> str:
128210 def __save(self):
129211 self.object_reader.save_typetree(self, self.__typetree__)
130212 clazz.__init__ = __init__
131- clazz.__repr__ = __repr__
213+ clazz.__repr__ = __repr__
132214 clazz.__typetree__ = typetree
133215 clazz.__fullname__ = fullname
134216 clazz.save = __save
@@ -137,6 +219,7 @@ def __save(self):
137219 return __inner
138220
139221
222+
140223# Helper functions
141224def UTTCGen_GetClass(src: MonoBehaviour | str) -> Type:
142225 """Get the class definition from MonoBehaviour or a full type name."""
@@ -261,6 +344,11 @@ def declare_field(name: str, type: str, org_type: str = None):
261344 if type not in {"object" , "List[object]" , "PPtr[object]" }:
262345 return f"{ name } : { type } "
263346 else :
347+ # We'd skip parsing these further if we don't know the type
348+ if type == "object" :
349+ type = 'dict'
350+ if type == "List[object]" :
351+ type = 'List[dict]'
264352 return f"{ name } : { type } # XXX: Fallback of { org_type } "
265353
266354
@@ -372,9 +460,7 @@ def __encoder(obj):
372460 continue # Nested
373461 if dep < pa_dep1 :
374462 # Skip parent fields at lvl1
375- continue
376- if i + 1 < len (fields ) and fields [i + 1 ].m_Type == "Array" :
377- field .m_Type = fields [i + 3 ].m_Type + "[]"
463+ continue
378464 name , type = field .m_Name , translate_type (
379465 field .m_Type , typenames = classname_nodes | import_defs
380466 )
@@ -518,7 +604,9 @@ def populate_gen():
518604 try :
519605 node = gen .get_nodes_as_json (asm , clz )
520606 node = json .loads (node )
521- # https://github.com/UnityPy-Org/TypeTreeGeneratorAPI/pull/4
607+ # https://github.com/UnityPy-Org/TypeTreeGeneratorAPI/pull/4
608+ if node and node [0 ]["m_Level" ] != 0 :
609+ node = Typetree_MonoBehaviour + node
522610 typetree [clz ] = node
523611 except Exception as e :
524612 logger .warning (f"Skipping nodes for { asm } .{ clz } : { e } " )
0 commit comments