CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-unitypy

A Unity asset extractor for Python based on AssetStudio that supports extraction, editing, and manipulation of Unity game assets.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

asset-export.mddocs/

Asset Export and Conversion

Comprehensive export capabilities for converting Unity assets to standard formats. Includes format conversion, compression options, and platform-specific optimizations for textures, audio, meshes, and other asset types.

Capabilities

Texture Export and Conversion

Convert Unity textures to standard image formats with format detection and platform-specific handling.

class Texture2DConverter:
    """
    Texture format conversion and export utilities.
    """
    
    @staticmethod
    def get_image_from_texture2d(texture_2d: Texture2D, flip: bool = True) -> Image.Image:
        """
        Convert Unity texture to PIL Image.
        
        Parameters:
        - texture_2d: Texture2D object
        - flip: Whether to flip image vertically
        
        Returns:
        PIL.Image.Image: Converted image
        """
    
    @staticmethod
    def image_to_texture2d(img: Image.Image, target_format: int, platform: int = 0, platform_blob: Optional[List[int]] = None) -> Tuple[bytes, int]:
        """
        Convert PIL Image to Unity texture format.
        
        Parameters:
        - img: PIL Image to convert
        - target_format: Target texture format ID
        - platform: Target platform
        - platform_blob: Platform-specific data
        
        Returns:
        Tuple[bytes, int]: Texture data bytes and actual format used
        """
    
    @staticmethod
    def parse_image_data(image_data: Union[bytes, bytearray, memoryview], width: int, height: int, texture_format: Union[TextureFormat, int], version: Tuple[int, int, int, int], platform: Union[BuildTarget, int], platform_blob: Optional[List[int]] = None, flip: bool = True) -> Image.Image:
        """
        Parse raw image data bytes to PIL Image.
        
        Parameters:
        - image_data: Raw texture data
        - width: Image width in pixels
        - height: Image height in pixels  
        - texture_format: Unity texture format
        - version: Unity version tuple
        - platform: Build target platform
        - platform_blob: Platform-specific data
        - flip: Whether to flip image vertically
        
        Returns:
        PIL.Image.Image: Parsed image
        """

Audio Export and Conversion

Convert Unity audio clips to standard audio formats with support for various compression methods.

class AudioClipConverter:
    """
    Audio format conversion and export utilities.
    """
    
    @staticmethod
    def extract_audioclip_samples(audio: AudioClip, convert_pcm_float: bool = True) -> Dict[str, bytes]:
        """
        Extract audio samples from AudioClip as WAV data.
        
        Parameters:
        - audio: AudioClip object
        - convert_pcm_float: Whether to convert PCM float to int16
        
        Returns:
        Dict[str, bytes]: Dictionary mapping sample names to WAV file bytes
        """
    
    @staticmethod
    def dump_samples(clip: AudioClip, audio_data: bytes, convert_pcm_float: bool = True) -> Dict[str, bytes]:
        """
        Extract samples from raw audio data.
        
        Parameters:
        - clip: AudioClip object for metadata
        - audio_data: Raw audio data bytes
        - convert_pcm_float: Whether to convert PCM float to int16
        
        Returns:
        Dict[str, bytes]: Dictionary mapping sample names to WAV file bytes
        """
    
    @staticmethod
    def subsound_to_wav(subsound, convert_pcm_float: bool = True) -> bytes:
        """
        Convert FMOD subsound to WAV format.
        
        Parameters:
        - subsound: FMOD subsound object
        - convert_pcm_float: Whether to convert PCM float to int16
        
        Returns:
        bytes: WAV audio data
        """

Mesh Export

Export Unity mesh data to standard 3D formats.

class MeshExporter:
    """
    Mesh export utilities for 3D formats.
    """
    
    @staticmethod
    def export_mesh(m_Mesh: Mesh, format: str = "obj") -> str:
        """
        Export mesh in specified format.
        
        Parameters:
        - m_Mesh: Mesh object
        - format: Output format ("obj" only currently supported)
        
        Returns:
        str: Mesh data in specified format
        """
    
    @staticmethod 
    def export_mesh_obj(mesh: Mesh, material_names: Optional[List[str]] = None) -> str:
        """
        Export mesh as Wavefront OBJ format.
        
        Parameters:
        - mesh: Mesh object
        - material_names: Optional list of material names
        
        Returns:
        str: OBJ format text data
        """

Mesh Renderer Export

Export rendered meshes with material information.

class MeshRendererExporter:
    """
    Export meshes with rendering information.
    """
    
    @staticmethod
    def export_mesh_renderer(renderer: Renderer, export_dir: str) -> None:
        """
        Export mesh renderer with materials to directory.
        
        Parameters:
        - renderer: Renderer object (MeshRenderer, SkinnedMeshRenderer)
        - export_dir: Directory to export files to
        """
    
    @staticmethod
    def get_mesh(meshR: Renderer) -> Optional[Mesh]:
        """
        Get mesh from renderer component.
        
        Parameters:
        - meshR: Renderer object
        
        Returns:
        Optional[Mesh]: Associated mesh object if found
        """
    
    @staticmethod
    def export_material(mat: Material) -> str:
        """
        Export material as text representation.
        
        Parameters:
        - mat: Material object
        
        Returns:
        str: Material data as string
        """

Sprite Processing

Extract and process Unity sprite assets with texture atlas support.

class SpriteHelper:
    """
    Sprite extraction and processing utilities.
    """
    
    @staticmethod
    def get_image_from_sprite(m_Sprite: Sprite) -> Image.Image:
        """
        Extract sprite as PIL Image with alpha channel merging.
        
        Parameters:
        - m_Sprite: Sprite object
        
        Returns:
        PIL.Image.Image: Extracted sprite image with proper alpha
        """
    
    @staticmethod
    def get_image(sprite: Sprite, texture: PPtr[Texture2D], alpha_texture: Optional[PPtr[Texture2D]]) -> Image.Image:
        """
        Get sprite image from texture with optional alpha texture.
        
        Parameters:
        - sprite: Sprite object
        - texture: Main texture reference
        - alpha_texture: Optional alpha texture reference
        
        Returns:
        PIL.Image.Image: Sprite image with alpha channel
        """
    
    @staticmethod
    def mask_sprite(m_Sprite: Sprite, mesh: MeshHandler, sprite_image: Image.Image) -> Image.Image:
        """
        Apply mesh mask to sprite image.
        
        Parameters:
        - m_Sprite: Sprite object
        - mesh: Mesh handler for masking
        - sprite_image: Source sprite image
        
        Returns:
        PIL.Image.Image: Masked sprite image
        """

Shader Conversion

Convert Unity shaders to readable formats.

class ShaderConverter:
    """
    Shader code conversion and export utilities.
    """
    
    @staticmethod
    def export_shader_code(shader):
        """
        Export shader source code.
        
        Parameters:
        - shader: Shader object
        
        Returns:
        str: Readable shader code
        """
    
    @staticmethod
    def export_shader_properties(shader):
        """
        Export shader properties and parameters.
        
        Parameters:
        - shader: Shader object
        
        Returns:
        dict: Shader properties and metadata
        """

Usage Examples

Exporting Textures

import UnityPy
from UnityPy.export import Texture2DConverter

env = UnityPy.load("texture_assets/")

for obj in env.objects:
    if obj.type.name == "Texture2D":
        texture = obj.read()
        
        # Method 1: Use built-in save method
        texture.save(f"exports/{texture.name}.png")
        
        # Method 2: Use converter for more control
        image = Texture2DConverter.export_PIL(texture)
        image.save(f"exports/{texture.name}_converted.png")
        
        # Method 3: Export as bytes
        png_data = Texture2DConverter.export_bytes(texture, "PNG")
        with open(f"exports/{texture.name}.png", "wb") as f:
            f.write(png_data)
        
        # Export in different formats
        jpeg_data = Texture2DConverter.export_bytes(texture, "JPEG")
        with open(f"exports/{texture.name}.jpg", "wb") as f:
            f.write(jpeg_data)

Processing Audio Files

import UnityPy
from UnityPy.export import AudioClipConverter
import numpy as np

env = UnityPy.load("audio_assets/")

for obj in env.objects:
    if obj.type.name == "AudioClip":
        audio = obj.read()
        
        # Method 1: Use built-in save method
        audio.save(f"exports/{audio.name}.wav")
        
        # Method 2: Use converter
        wav_data = AudioClipConverter.export_wav(audio)
        with open(f"exports/{audio.name}_converted.wav", "wb") as f:
            f.write(wav_data)
        
        # Get raw audio samples for processing
        samples = AudioClipConverter.get_samples(audio)
        print(f"Audio samples shape: {samples.shape}")
        print(f"Sample rate: {audio.m_Frequency}")
        
        # Process samples (example: reduce volume)
        processed_samples = samples * 0.5
        
        # Export OGG format
        try:
            ogg_data = AudioClipConverter.export_ogg(audio)
            with open(f"exports/{audio.name}.ogg", "wb") as f:
                f.write(ogg_data)
        except Exception as e:
            print(f"OGG export failed: {e}")

Exporting Meshes

import UnityPy
from UnityPy.export import MeshExporter

env = UnityPy.load("mesh_assets/")

for obj in env.objects:
    if obj.type.name == "Mesh":
        mesh = obj.read()
        
        # Export as OBJ format
        obj_data = MeshExporter.export_obj(mesh)
        with open(f"exports/{mesh.name}.obj", "w") as f:
            f.write(obj_data)
        
        # Export as PLY format
        ply_data = MeshExporter.export_ply(mesh)
        with open(f"exports/{mesh.name}.ply", "w") as f:
            f.write(ply_data)
        
        # Export just vertices for analysis
        vertices = MeshExporter.export_vertices(mesh)
        print(f"Mesh {mesh.name}: {len(vertices)} vertices")
        
        # Export vertex data as CSV
        import csv
        with open(f"exports/{mesh.name}_vertices.csv", "w", newline="") as f:
            writer = csv.writer(f)
            writer.writerow(["x", "y", "z"])
            writer.writerows(vertices)

Extracting Sprites

import UnityPy
from UnityPy.export import SpriteHelper

env = UnityPy.load("sprite_assets/")

sprites = []
textures = {}

# First, collect all textures
for obj in env.objects:
    if obj.type.name == "Texture2D":
        texture = obj.read()
        textures[obj.path_id] = texture
    elif obj.type.name == "Sprite":
        sprites.append(obj)

# Export sprites
for sprite_obj in sprites:
    sprite = sprite_obj.read()
    
    # Method 1: Direct sprite export
    sprite_image = SpriteHelper.export_sprite(sprite)
    sprite_image.save(f"exports/{sprite.name}.png")
    
    # Method 2: Manual cropping from texture
    if sprite.texture.path_id in textures:
        source_texture = textures[sprite.texture.path_id]
        cropped = SpriteHelper.crop_sprite_from_texture(source_texture, sprite)
        cropped.save(f"exports/{sprite.name}_cropped.png")
    
    # Export as bytes
    sprite_bytes = SpriteHelper.export_sprite_bytes(sprite, "PNG")
    with open(f"exports/{sprite.name}_bytes.png", "wb") as f:
        f.write(sprite_bytes)

Batch Export Operations

import UnityPy
import os
from pathlib import Path

def export_all_assets(asset_path, output_dir):
    """Export all supported assets from a Unity project."""
    
    env = UnityPy.load(asset_path)
    output_path = Path(output_dir)
    
    # Create output directories
    (output_path / "textures").mkdir(parents=True, exist_ok=True)
    (output_path / "audio").mkdir(parents=True, exist_ok=True)
    (output_path / "meshes").mkdir(parents=True, exist_ok=True)
    (output_path / "sprites").mkdir(parents=True, exist_ok=True)
    
    export_counts = {"textures": 0, "audio": 0, "meshes": 0, "sprites": 0}
    
    for obj in env.objects:
        try:
            if obj.type.name == "Texture2D":
                texture = obj.read()
                safe_name = "".join(c for c in texture.name if c.isalnum() or c in "._-")
                texture.save(output_path / "textures" / f"{safe_name}.png")
                export_counts["textures"] += 1
                
            elif obj.type.name == "AudioClip":
                audio = obj.read()
                safe_name = "".join(c for c in audio.name if c.isalnum() or c in "._-")
                audio.save(output_path / "audio" / f"{safe_name}.wav")
                export_counts["audio"] += 1
                
            elif obj.type.name == "Mesh":
                mesh = obj.read()
                safe_name = "".join(c for c in mesh.name if c.isalnum() or c in "._-")
                obj_data = MeshExporter.export_obj(mesh)
                with open(output_path / "meshes" / f"{safe_name}.obj", "w") as f:
                    f.write(obj_data)
                export_counts["meshes"] += 1
                
            elif obj.type.name == "Sprite":
                sprite = obj.read()
                safe_name = "".join(c for c in sprite.name if c.isalnum() or c in "._-")
                sprite_image = SpriteHelper.export_sprite(sprite)
                sprite_image.save(output_path / "sprites" / f"{safe_name}.png")
                export_counts["sprites"] += 1
                
        except Exception as e:
            print(f"Failed to export {obj.type.name}: {e}")
    
    print(f"Export complete:")
    for asset_type, count in export_counts.items():
        print(f"  {asset_type}: {count}")

# Usage
export_all_assets("game_assets/", "extracted_assets/")

Advanced Format Conversion

import UnityPy
from UnityPy.export import Texture2DConverter
from PIL import Image

env = UnityPy.load("texture_assets/")

for obj in env.objects:
    if obj.type.name == "Texture2D":
        texture = obj.read()
        
        # Get original format info
        print(f"Original format: {texture.m_TextureFormat}")
        print(f"Size: {texture.m_Width}x{texture.m_Height}")
        
        # Convert to PIL for processing
        image = Texture2DConverter.export_PIL(texture)
        
        # Apply processing
        if image.mode == "RGBA":
            # Convert RGBA to RGB with white background
            rgb_image = Image.new("RGB", image.size, (255, 255, 255))
            rgb_image.paste(image, mask=image.split()[-1])  # Use alpha as mask
            
            # Save processed version
            rgb_image.save(f"exports/{texture.name}_rgb.jpg", quality=95)
        
        # Create thumbnail
        thumbnail = image.copy()
        thumbnail.thumbnail((128, 128), Image.LANCZOS)
        thumbnail.save(f"exports/{texture.name}_thumb.png")
        
        # Export multiple formats
        formats = [
            ("PNG", "png"),
            ("JPEG", "jpg"), 
            ("WEBP", "webp")
        ]
        
        for format_name, ext in formats:
            try:
                converted_bytes = Texture2DConverter.export_bytes(texture, format_name)
                with open(f"exports/{texture.name}.{ext}", "wb") as f:
                    f.write(converted_bytes)
            except Exception as e:
                print(f"Failed to convert to {format_name}: {e}")

Install with Tessl CLI

npx tessl i tessl/pypi-unitypy

docs

asset-classes.md

asset-export.md

asset-loading.md

binary-data.md

enumerations.md

file-formats.md

index.md

tile.json