Skip to content

Instantly share code, notes, and snippets.

@helloqinglan
Created July 4, 2015 03:21
Show Gist options
  • Save helloqinglan/9a233e0f575df9386c10 to your computer and use it in GitHub Desktop.
Save helloqinglan/9a233e0f575df9386c10 to your computer and use it in GitHub Desktop.
extract textures and meshes from asset bundles
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
public class AssetBundleExtract : MonoBehaviour {
private string resdir = "~/Work/UnityProj/GameRes/Raw/";
private string outputdir = "~/Work/UnityProj/Gameres/Output/";
private string textureFolder = "Texture";
private string meshFolder = "Mesh";
private GameObject planeObj = null;
private Transform planeTrans = null;
private int planeWidth = 1024;
private int planeHeight = 1024;
// Use this for initialization
void Start () {
planeObj = GameObject.Find("Plane");
planeTrans = planeObj.transform;
StartCoroutine(LoadAssets());
}
private IEnumerator LoadAssets() {
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(resdir + "HashSourceList.xml");
XmlNode rootNode = xmlDoc.SelectSingleNode("Root");
XmlNodeList nodeList = rootNode.ChildNodes;
foreach (XmlNode node in nodeList) {
string name = node.Attributes["name"].Value;
string folder = resdir + node.Attributes["path"].Value;
yield return StartCoroutine(LoadAsset(name, folder));
}
Debug.Log("work finished!!!");
}
private IEnumerator LoadAsset(string assetName, string assetPath) {
WWW download = new WWW ("file://" + assetPath);
yield return download;
if ( download.error != null ) {
Debug.LogError( download.error );
download.Dispose();
yield break;
}
AssetBundle assetBundle = download.assetBundle;
if (assetBundle == null) {
Debug.LogWarning("invalid asset bundle: " + assetName);
yield break;
}
Object[] assetList = assetBundle.LoadAll();
foreach (Object o in assetList) {
if (o.GetType() == typeof(Texture2D)) {
Texture2D tex = o as Texture2D;
yield return StartCoroutine(SaveTexture2D(tex));
} else if (o.GetType() == typeof(Mesh)) {
Mesh mesh = o as Mesh;
yield return StartCoroutine(SaveMesh(mesh));
} else if (o.GetType() == typeof(AnimationClip)) {
} else if (o.GetType() == typeof(Material)) {
} else if (o.GetType() == typeof(Avatar)) {
} else if (o.GetType() == typeof(GameObject)) {
} else if (o.GetType() == typeof(MonoScript)) {
} else if (o.GetType() == typeof(Transform)) {
} else if (o.GetType() == typeof(Shader)) {
} else if (o.GetType() == typeof(AudioClip)) {
} else if (o.GetType() == typeof(Sprite)) {
} else if (o.GetType() == typeof(Animation)) {
} else if (o.GetType() == typeof(Animator)) {
} else if (o.GetType() == typeof(UnityEditorInternal.AnimatorController)) {
} else if (o.GetType() == typeof(TextAsset)) {
} else {
Debug.LogError("asset type: " + o.GetType());
}
}
assetBundle.Unload(true);
download.Dispose();
download = null;
}
private IEnumerator SaveTexture2D(Texture2D tex) {
planeWidth = tex.width;
planeHeight = tex.height;
float scaleX = 1.0f;
float scaleY = 1.0f;
float posX = 0.0f;
float posY = 1.0f;
if (planeWidth == 1024) {
scaleX = 1.0f;
posX = 0.0f;
} else if (planeWidth == 512) {
scaleX = 0.5f;
posX = 2.5f;
} else if (planeWidth == 256) {
scaleX = 0.25f;
posX = 3.75f;
} else if (planeWidth == 128) {
scaleX = 0.125f;
posX = 4.375f;
} else if (planeWidth == 64) {
scaleX = 0.0625f;
posX = 4.40625f;
} else if (planeWidth == 32) {
scaleX = 0.03125f;
posX = 4.421875f;
} else {
Debug.LogWarning("invalid texture width: " + planeWidth);
yield break;
}
if (planeHeight == 1024) {
scaleY = 1.0f;
posY = 1.0f;
} else if (planeHeight == 512) {
scaleY = 0.5f;
posY = -1.5f;
} else if (planeHeight == 256) {
scaleY = 0.25f;
posY = -2.75f;
} else if (planeHeight == 128) {
scaleY = 0.125f;
posY = -3.375f;
} else if (planeHeight == 64) {
scaleY = 0.0625f;
posY = -3.40625f;
} else if (planeHeight == 32) {
scaleY = 0.03125f;
posY = -3.421875f;
} else {
Debug.LogWarning("invalid texture height: " + planeHeight);
yield break;
}
planeTrans.position = new Vector3(posX, posY, 0.0f);
planeTrans.localScale = new Vector3(scaleX, 1.0f, scaleY);
planeObj.renderer.material.mainTexture = tex;
yield return new WaitForEndOfFrame();
Texture2D screenTex = new Texture2D(planeWidth, planeHeight, TextureFormat.RGB24, false);
screenTex.ReadPixels(new Rect(0, 0, planeWidth, planeHeight), 0, 0, false);
screenTex.Apply();
byte[] data = screenTex.EncodeToPNG();
Destroy(screenTex);
File.WriteAllBytes(outputdir + textureFolder + "/" + tex.name + ".png", data);
yield return new WaitForEndOfFrame();
}
private IEnumerator SaveMesh(Mesh mesh) {
MeshExporter.MeshToFile(mesh, outputdir + meshFolder + "/" + mesh.name + ".obj");
yield return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment