A Unity asset extractor for Python based on AssetStudio that supports extraction, editing, and manipulation of Unity game assets.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Complete collection of Unity asset types including textures, audio, meshes, shaders, and game objects. Each class provides typed access to Unity's native data structures with methods for reading, modifying, and exporting assets.
Foundation class that provides access to Unity objects with core functionality for reading and saving asset data. This is the interface used to access objects from loaded asset files.
class ObjectReader:
"""
Reader interface for Unity objects providing typed access to asset data.
"""
@property
def type(self) -> ClassIDType:
"""
Get the ClassIDType of this object.
Returns:
ClassIDType: The Unity class type identifier
"""
@property
def path_id(self) -> int:
"""
Get the unique path ID of this object within its asset file.
Returns:
int: Object path ID
"""
@property
def class_id(self) -> int:
"""
Get the numeric class ID.
Returns:
int: Unity class ID number
"""
def read(self, check_read: bool = True) -> T:
"""
Read object data as a parsed Unity class instance.
Parameters:
- check_read: Whether to validate read operation
Returns:
T: Parsed object instance with typed properties
"""
def read_typetree(self, nodes: Optional[NodeInput] = None, wrap: bool = False, check_read: bool = True) -> Union[dict, T]:
"""
Read object data using typetree system.
Parameters:
- nodes: Optional type tree nodes
- wrap: Whether to wrap result in object class
- check_read: Whether to validate read operation
Returns:
Union[dict, T]: Raw dictionary or wrapped object instance
"""
def save_typetree(self, tree: Union[dict, T], nodes: Optional[NodeInput] = None, writer: Optional[EndianBinaryWriter] = None):
"""
Save modified object data from dictionary or object instance.
Parameters:
- tree: Modified object data as dict or object instance
- nodes: Optional type tree nodes
- writer: Optional binary writer
"""
def get_raw_data(self) -> bytes:
"""
Get raw binary data of the object.
Returns:
bytes: Raw object data
"""
def set_raw_data(self, data: bytes):
"""
Set raw binary data for the object.
Parameters:
- data: New raw object data
"""Base class for all parsed Unity asset instances that provides common functionality.
class Object:
"""
Base class for all Unity asset instances.
"""
object_reader: Optional[ObjectReader]
def save(self) -> None:
"""
Save this object's changes back to the asset file.
Calls save_typetree on the associated ObjectReader.
"""Classes for working with Unity texture assets including 2D textures and texture arrays.
class Texture2D(Object):
"""
Unity 2D texture asset with format conversion and export capabilities.
"""
m_Name: str
m_Width: int
m_Height: int
m_TextureFormat: int
m_CompleteImageSize: int
m_IsReadable: bool
image_data: bytes
m_StreamData: Optional[StreamingInfo]
m_MipMap: Optional[bool]
m_MipCount: Optional[int]
@property
def image(self) -> Image.Image:
"""
Get texture as PIL Image with automatic format conversion.
Returns:
PIL.Image.Image: Decoded image data ready for manipulation
"""
@image.setter
def image(self, img: Union[Image.Image, str, BinaryIO]):
"""
Set texture from PIL Image, file path, or file-like object.
Parameters:
- img: PIL Image, file path string, or file-like object
"""
def set_image(self, img: Union[Image.Image, str, BinaryIO], target_format: Optional[int] = None, mipmap_count: int = 1):
"""
Set texture image with format and mipmap control.
Parameters:
- img: PIL Image, file path, or file-like object
- target_format: Target texture format (uses current if None)
- mipmap_count: Number of mipmap levels to generate
"""
def get_image_data(self) -> bytes:
"""
Get raw image data bytes, loading from stream if necessary.
Returns:
bytes: Raw texture data in Unity format
"""
class Texture2DArray:
"""
Unity 2D texture array for advanced rendering techniques.
"""
@property
def name(self):
"""Texture array name."""
@property
def m_Width(self):
"""Texture width in pixels."""
@property
def m_Height(self):
"""Texture height in pixels."""
@property
def m_Depth(self):
"""Number of textures in the array."""
@property
def m_TextureFormat(self):
"""Pixel format of textures in the array."""Classes for Unity audio clips with format conversion and export functionality.
class AudioClip(Object):
"""
Unity audio clip with conversion and export capabilities.
"""
m_Name: str
m_Length: Optional[float]
m_Frequency: Optional[int]
m_Channels: Optional[int]
m_BitsPerSample: Optional[int]
m_CompressionFormat: Optional[int]
m_LoadType: Optional[int]
m_3D: Optional[bool]
m_AudioData: Optional[List[int]]
m_Resource: Optional[StreamedResource]
@property
def samples(self) -> Dict[str, bytes]:
"""
Get decoded audio samples as WAV data.
Returns:
Dict[str, bytes]: Dictionary mapping sample names to WAV file bytes
"""
@property
def extension(self) -> str:
"""
Get file extension based on compression format.
Returns:
str: File extension (.wav, .ogg, .mp3, etc.)
"""Classes for Unity mesh data including vertices, triangles, and material information.
class Mesh:
"""
Unity mesh asset containing 3D geometry data.
"""
@property
def name(self):
"""Mesh name."""
@property
def vertices(self):
"""
Vertex positions.
Returns:
List[Vector3f]: 3D vertex coordinates
"""
@property
def triangles(self):
"""
Triangle indices.
Returns:
List[int]: Vertex indices forming triangles
"""
@property
def normals(self):
"""
Vertex normals.
Returns:
List[Vector3f]: Normal vectors for lighting
"""
@property
def uv(self):
"""
UV texture coordinates.
Returns:
List[Vector2f]: Texture mapping coordinates
"""
@property
def colors(self):
"""
Vertex colors.
Returns:
List[ColorRGBA32]: Per-vertex color data
"""Classes for Unity 2D sprite assets with texture references and metadata.
class Sprite:
"""
Unity sprite asset for 2D graphics.
"""
@property
def name(self):
"""Sprite name."""
@property
def texture(self):
"""
Associated texture asset.
Returns:
PPtr[Texture2D]: Reference to texture
"""
@property
def textureRect(self):
"""
Rectangle defining sprite area in texture.
Returns:
Rectf: Sprite bounds in texture coordinates
"""
@property
def pivot(self):
"""
Sprite pivot point.
Returns:
Vector2f: Pivot coordinates
"""Classes for Unity game objects and scene hierarchy.
class GameObject:
"""
Unity game object - container for components in scenes.
"""
@property
def name(self):
"""Game object name."""
@property
def m_Component(self):
"""
List of attached components.
Returns:
List[ComponentPair]: Component references
"""
@property
def m_Layer(self):
"""
Rendering layer.
Returns:
int: Layer index
"""
@property
def m_IsActive(self):
"""
Whether the game object is active.
Returns:
bool: Active state
"""Classes for Unity rendering components and materials.
class Renderer:
"""
Base class for Unity renderer components.
"""
@property
def m_Materials(self):
"""
List of materials used by this renderer.
Returns:
List[PPtr[Material]]: Material references
"""
@property
def m_Enabled(self):
"""
Whether the renderer is enabled.
Returns:
bool: Enabled state
"""Classes for Unity shader assets and GPU programs.
class Shader:
"""
Unity shader asset containing GPU programs.
"""
@property
def name(self):
"""Shader name."""
@property
def m_ParsedForm(self):
"""
Parsed shader data.
Returns:
SerializedShader: Structured shader information
"""Class for managing references between Unity objects across files.
class PPtr:
"""
Smart pointer for referencing Unity objects.
"""
@property
def file_id(self):
"""
Source file identifier.
Returns:
int: File ID containing the referenced object
"""
@property
def path_id(self):
"""
Object identifier within file.
Returns:
int: Unique object ID
"""
def resolve(self):
"""
Resolve pointer to actual object.
Returns:
Object: Referenced Unity object
"""import UnityPy
env = UnityPy.load("texture_assets/")
for obj in env.objects:
if obj.type.name == "Texture2D":
texture = obj.read()
print(f"Texture: {texture.name}")
print(f"Size: {texture.m_Width}x{texture.m_Height}")
print(f"Format: {texture.m_TextureFormat}")
# Export as PNG
texture.save(f"exports/{texture.name}.png")
# Get as PIL Image for processing
image = texture.image
resized = image.resize((256, 256))
resized.save(f"exports/{texture.name}_resized.png")import UnityPy
env = UnityPy.load("audio_assets/")
for obj in env.objects:
if obj.type.name == "AudioClip":
audio = obj.read()
print(f"Audio: {audio.name}")
print(f"Length: {audio.m_Length:.2f}s")
print(f"Sample Rate: {audio.m_Frequency}Hz")
print(f"Channels: {audio.m_Channels}")
# Export as WAV
audio.save(f"exports/{audio.name}.wav")
# Get raw samples for processing
samples = audio.samples
print(f"Sample data shape: {samples.shape}")import UnityPy
env = UnityPy.load("mesh_assets/")
for obj in env.objects:
if obj.type.name == "Mesh":
mesh = obj.read()
print(f"Mesh: {mesh.name}")
print(f"Vertices: {len(mesh.vertices)}")
print(f"Triangles: {len(mesh.triangles) // 3}")
# Access vertex data
for i, vertex in enumerate(mesh.vertices[:5]): # First 5 vertices
print(f"Vertex {i}: ({vertex.x}, {vertex.y}, {vertex.z})")
# Access UV coordinates if available
if mesh.uv:
print(f"UV coordinates: {len(mesh.uv)}")import UnityPy
env = UnityPy.load("scene_assets/")
for obj in env.objects:
if obj.type.name == "GameObject":
gameobj = obj.read()
# Modify properties
gameobj.name = f"Modified_{gameobj.name}"
gameobj.m_IsActive = False
# Save changes
obj.save(gameobj)
# Save modified assets
env.save(out_path="modified_scene/")import UnityPy
env = UnityPy.load("custom_assets/")
for obj in env.objects:
# For any object type, even unknown ones
raw_data = obj.read_typetree()
print(f"Object type: {obj.type.name}")
print(f"Properties: {list(raw_data.keys())}")
# Modify via dictionary
if "m_Name" in raw_data:
raw_data["m_Name"] = f"Modified_{raw_data['m_Name']}"
obj.save_typetree(raw_data)Install with Tessl CLI
npx tessl i tessl/pypi-unitypy