Skip to content
Texture2D exporter, kind of
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Unity Texture Toolkit

written in PHP

What's this for

I wrote this for automatic game resource updating and dumping to png/webp, it's currently deployed on my server
Main codes are highly inspired by AssetStudio


php-ext-lz4 ( For decompressing the bundle )
astcenc ( For decompressing ASTC texture format )
ffmpeg ( For reencoding )
astcenc and ffmepg need to be placed under PATH, like /usr/bin (cron may not search for /usr/local/bin, or you can configure it)


Current supported format:

  • ASTC compressed 2d image
  • Raw rgb ( e.g. RGB24 RGB565 RGBA4444 etc )

I've only met these formats so far

How to use

require_once 'UnityAsset.php'; // This will require UnityBundle.php as it needs FileStream

$bundleFileName = 'bundle_name.unity3d'; // This is the bundle file with file header "UnityFS"
$bundleFileStream = new FileStream($bundleFileName); // Create a read stream
$assetsList = extractBundle($bundleFileStream); // This will extract assets to disk
unset($bundleFileStream); // Free the handle

foreach ($assetsList as $asset) {
  if (substr($asset, -4,4) == '.resS') continue; // .resS file is external data storage file
  $asset = new AssetFile($asset);

  foreach ($asset->preloadTable as &$item) {
    if ($item->typeString == 'Texture2D') {
      $item = new Texture2D($item, true); // Parse and read data
      $item->exportTo($item->name, 'webp', '-lossless 1'); // export to format, with additional encode parameters
      // $item->exportTo($item->name, 'png');
      unset($item); // Free up memory
  unset($asset); // Free up memory
foreach ($assetsList as $asset) {
  unlink($asset); // clean up files

What's in the sub directory

These are the files I'm croning on my server for automatic update
There are different versions, as I wrote the Princess Connect Re:dive first, its code has least feature, and cgss is the current latest
They all share the same UnityBundle.php

Implementation detail

  1. UnityBundle.php

class FileStream($filename) and MemoryStream($data):
Two similar stream reader, FileStream accepts filename, MemoryStream accepts string as binary.
Reading value can perform either function $stream->readInt32() or property $stream->ulong
Property position can get current and set to seek point
Property littleEndian determine either use little endian reading or not
Function write($newData) will always write to the end for MemoryStream, but can overwrite current data position for FileStream

function extractBundle($bundleStream):
Accepts a stream, may throw exception if is invalid file, or chunk is LZMA compressed, or something wrong happened
Returns a list of asset file names extracted

  1. UnityAsset.php

class AssetFile($assetFileName):
Accepts a filename, may throw exception if something is not supported
Can get resource info through property preloadTable

class Texture2D($preloadData, $readSwitch = false):
Accepts an AssetPreloadData item from preloadTable, may throw an exception if format not supported
Second parameter determine weither read data or not, if you only want to get the information
Can call member function exportTo($saveTo, $format = 'png', $extraEncodeParam = '') to export supported texture

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.