mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-05-25 05:40:21 -04:00
- workaround for Unity 5 vertex buffer anomaly
- re-wrote code for loading and extracting bundle files - fixed link problem with instances of skinned geometry - separated normal and bump map texture slots in FBX - added transparency factor in FBX materials
This commit is contained in:
parent
1f2635c877
commit
32855d932e
@ -8,10 +8,9 @@ using Lz4;
|
|||||||
|
|
||||||
namespace Unity_Studio
|
namespace Unity_Studio
|
||||||
{
|
{
|
||||||
public class BundleFile : IDisposable
|
public class BundleFile
|
||||||
{
|
{
|
||||||
private EndianStream Stream;
|
public int ver1;
|
||||||
public byte ver1;
|
|
||||||
public string ver2;
|
public string ver2;
|
||||||
public string ver3;
|
public string ver3;
|
||||||
public List<MemoryAssetsFile> MemoryAssetsFileList = new List<MemoryAssetsFile>();
|
public List<MemoryAssetsFile> MemoryAssetsFileList = new List<MemoryAssetsFile>();
|
||||||
@ -52,84 +51,101 @@ namespace Unity_Studio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream = new EndianStream(new MemoryStream(filebuffer), EndianType.BigEndian);
|
using (var b_Stream = new EndianStream(new MemoryStream(filebuffer), EndianType.BigEndian))
|
||||||
|
{
|
||||||
|
readBundle(b_Stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else { Stream = new EndianStream(File.OpenRead(fileName), EndianType.BigEndian); }
|
else
|
||||||
|
|
||||||
long magicHeader = Stream.ReadInt64();
|
|
||||||
|
|
||||||
if (magicHeader == -361700864190383366 || magicHeader == 6155973689634940258 || magicHeader == 6155973689634611575)
|
|
||||||
{
|
{
|
||||||
int dummy = Stream.ReadInt32();
|
using (var b_Stream = new EndianStream(File.OpenRead(fileName), EndianType.BigEndian))
|
||||||
ver1 = Stream.ReadByte();
|
{
|
||||||
ver2 = Stream.ReadStringToNull();
|
readBundle(b_Stream);
|
||||||
ver3 = Stream.ReadStringToNull();
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readBundle(EndianStream b_Stream)
|
||||||
|
{
|
||||||
|
var header = b_Stream.ReadStringToNull();
|
||||||
|
|
||||||
|
if (header == "UnityWeb" || header == "UnityRaw" || header == "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA")
|
||||||
|
{
|
||||||
|
ver1 = b_Stream.ReadInt32();
|
||||||
|
ver2 = b_Stream.ReadStringToNull();
|
||||||
|
ver3 = b_Stream.ReadStringToNull();
|
||||||
|
if (ver1 < 6) { int bundleSize = b_Stream.ReadInt32(); }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
long bundleSize = b_Stream.ReadInt64();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
short dummy2 = b_Stream.ReadInt16();
|
||||||
|
int offset = b_Stream.ReadInt16();
|
||||||
|
int dummy3 = b_Stream.ReadInt32();
|
||||||
|
int lzmaChunks = b_Stream.ReadInt32();
|
||||||
|
|
||||||
int lzmaSize = 0;
|
int lzmaSize = 0;
|
||||||
int fileSize = Stream.ReadInt32();
|
long streamSize = 0;
|
||||||
short dummy2 = Stream.ReadInt16();
|
|
||||||
int offset = Stream.ReadInt16();
|
|
||||||
int dummy3 = Stream.ReadInt32();
|
|
||||||
int lzmaChunks = Stream.ReadInt32();
|
|
||||||
|
|
||||||
for (int i = 0; i < lzmaChunks; i++)
|
for (int i = 0; i < lzmaChunks; i++)
|
||||||
{
|
{
|
||||||
lzmaSize = Stream.ReadInt32();
|
lzmaSize = b_Stream.ReadInt32();
|
||||||
fileSize = Stream.ReadInt32();
|
streamSize = b_Stream.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream.Position = offset;
|
b_Stream.Position = offset;
|
||||||
switch (magicHeader)
|
switch (header)
|
||||||
{
|
{
|
||||||
case -361700864190383366: //.bytes
|
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA": //.bytes
|
||||||
case 6155973689634940258: //UnityWeb
|
case "UnityWeb":
|
||||||
{
|
{
|
||||||
byte[] lzmaBuffer = new byte[lzmaSize];
|
byte[] lzmaBuffer = new byte[lzmaSize];
|
||||||
Stream.Read(lzmaBuffer, 0, lzmaSize);
|
b_Stream.Read(lzmaBuffer, 0, lzmaSize);
|
||||||
Stream.Close();
|
|
||||||
Stream.Dispose();
|
|
||||||
|
|
||||||
Stream = new EndianStream(SevenZip.Compression.LZMA.SevenZipHelper.StreamDecompress(new MemoryStream(lzmaBuffer)), EndianType.BigEndian);
|
using (var lzmaStream = new EndianStream(SevenZip.Compression.LZMA.SevenZipHelper.StreamDecompress(new MemoryStream(lzmaBuffer)), EndianType.BigEndian))
|
||||||
offset = 0;
|
{
|
||||||
|
getFiles(lzmaStream, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 6155973689634611575: //UnityRaw
|
case "UnityRaw":
|
||||||
{
|
{
|
||||||
|
getFiles(b_Stream, offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int fileCount = Stream.ReadInt32();
|
|
||||||
for (int i = 0; i < fileCount; i++)
|
|
||||||
{
|
|
||||||
MemoryAssetsFile memFile = new MemoryAssetsFile();
|
|
||||||
memFile.fileName = Stream.ReadStringToNull();
|
|
||||||
int fileOffset = Stream.ReadInt32();
|
|
||||||
fileOffset += offset;
|
|
||||||
fileSize = Stream.ReadInt32();
|
|
||||||
long nextFile = Stream.Position;
|
|
||||||
Stream.Position = fileOffset;
|
|
||||||
|
|
||||||
byte[] buffer = new byte[fileSize];
|
|
||||||
Stream.Read(buffer, 0, fileSize);
|
|
||||||
memFile.memStream = new MemoryStream(buffer);
|
|
||||||
MemoryAssetsFileList.Add(memFile);
|
|
||||||
Stream.Position = nextFile;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (header == "UnityFS")
|
||||||
Stream.Close();
|
{
|
||||||
|
ver1 = b_Stream.ReadInt32();
|
||||||
|
ver2 = b_Stream.ReadStringToNull();
|
||||||
|
ver3 = b_Stream.ReadStringToNull();
|
||||||
|
long bundleSize = b_Stream.ReadInt64();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~BundleFile()
|
private void getFiles(EndianStream f_Stream, int offset)
|
||||||
{
|
{
|
||||||
Dispose();
|
int fileCount = f_Stream.ReadInt32();
|
||||||
}
|
for (int i = 0; i < fileCount; i++)
|
||||||
|
{
|
||||||
|
MemoryAssetsFile memFile = new MemoryAssetsFile();
|
||||||
|
memFile.fileName = f_Stream.ReadStringToNull();
|
||||||
|
int fileOffset = f_Stream.ReadInt32();
|
||||||
|
fileOffset += offset;
|
||||||
|
int fileSize = f_Stream.ReadInt32();
|
||||||
|
long nextFile = f_Stream.Position;
|
||||||
|
f_Stream.Position = fileOffset;
|
||||||
|
|
||||||
public void Dispose()
|
byte[] buffer = new byte[fileSize];
|
||||||
{
|
f_Stream.Read(buffer, 0, fileSize);
|
||||||
Stream.Dispose();
|
memFile.memStream = new MemoryStream(buffer);
|
||||||
GC.SuppressFinalize(this);
|
MemoryAssetsFileList.Add(memFile);
|
||||||
|
f_Stream.Position = nextFile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -583,6 +583,8 @@ namespace Unity_Studio
|
|||||||
|
|
||||||
BitArray m_CurrentChannels = new BitArray(new int[1] { a_Stream.ReadInt32() });
|
BitArray m_CurrentChannels = new BitArray(new int[1] { a_Stream.ReadInt32() });
|
||||||
m_VertexCount = a_Stream.ReadInt32();
|
m_VertexCount = a_Stream.ReadInt32();
|
||||||
|
//int singleStreamStride = 0;//used tor unity 5
|
||||||
|
int streamCount = 0;
|
||||||
|
|
||||||
#region streams for 3.5.0 - 3.5.7
|
#region streams for 3.5.0 - 3.5.7
|
||||||
if (version[0] < 4)
|
if (version[0] < 4)
|
||||||
@ -608,9 +610,6 @@ namespace Unity_Studio
|
|||||||
#region channels and streams for 4.0.0 and later
|
#region channels and streams for 4.0.0 and later
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//int singleStreamStride = 0;//used tor unity 5
|
|
||||||
int streamCount = 0;
|
|
||||||
|
|
||||||
m_Channels = new ChannelInfo[a_Stream.ReadInt32()];
|
m_Channels = new ChannelInfo[a_Stream.ReadInt32()];
|
||||||
for (int c = 0; c < m_Channels.Length; c++)
|
for (int c = 0; c < m_Channels.Length; c++)
|
||||||
{
|
{
|
||||||
@ -639,28 +638,49 @@ namespace Unity_Studio
|
|||||||
m_Streams[s].frequency = a_Stream.ReadUInt16();
|
m_Streams[s].frequency = a_Stream.ReadUInt16();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //create streams
|
|
||||||
{
|
|
||||||
m_Streams = new StreamInfo[streamCount];
|
|
||||||
for (int s = 0; s < streamCount; s++)
|
|
||||||
{
|
|
||||||
m_Streams[s] = new StreamInfo();
|
|
||||||
m_Streams[s].channelMask = new BitArray(new int[1] { 0 });
|
|
||||||
m_Streams[s].offset = 0;
|
|
||||||
if (s > 0) { m_Streams[s].offset = m_Streams[s - 1].offset + m_Streams[s - 1].stride * m_VertexCount; }
|
|
||||||
m_Streams[s].stride = 0;
|
|
||||||
foreach (var m_Channel in m_Channels)
|
|
||||||
{
|
|
||||||
if (m_Channel.stream == s) { m_Streams[s].stride += m_Channel.dimension * (4 / (int)Math.Pow(2, m_Channel.format)); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
//actual Vertex Buffer
|
//actual Vertex Buffer
|
||||||
byte[] m_DataSize = new byte[a_Stream.ReadInt32()];
|
byte[] m_DataSize = new byte[a_Stream.ReadInt32()];
|
||||||
a_Stream.Read(m_DataSize, 0, m_DataSize.Length);
|
a_Stream.Read(m_DataSize, 0, m_DataSize.Length);
|
||||||
|
|
||||||
|
if (version[0] >= 5) //create streams
|
||||||
|
{
|
||||||
|
m_Streams = new StreamInfo[streamCount];
|
||||||
|
for (int s = 0; s < streamCount; s++)
|
||||||
|
{
|
||||||
|
m_Streams[s] = new StreamInfo();
|
||||||
|
m_Streams[s].channelMask = new BitArray(new int[1] { 0 });
|
||||||
|
m_Streams[s].offset = 0;
|
||||||
|
m_Streams[s].stride = 0;
|
||||||
|
|
||||||
|
foreach (var m_Channel in m_Channels)
|
||||||
|
{
|
||||||
|
if (m_Channel.stream == s) { m_Streams[s].stride += m_Channel.dimension * (4 / (int)Math.Pow(2, m_Channel.format)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s > 0)
|
||||||
|
{
|
||||||
|
m_Streams[s].offset = m_Streams[s - 1].offset + m_Streams[s - 1].stride * m_VertexCount;
|
||||||
|
//sometimes there are 8 bytes between streams
|
||||||
|
//this is NOT an alignment, even if sometimes it may seem so
|
||||||
|
|
||||||
|
if (streamCount == 2) { m_Streams[s].offset = m_DataSize.Length - m_Streams[s].stride * m_VertexCount; }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_VertexCount = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*var absoluteOffset = a_Stream.Position + 4 + m_Streams[s].offset;
|
||||||
|
if ((absoluteOffset % m_Streams[s].stride) != 0)
|
||||||
|
{
|
||||||
|
m_Streams[s].offset += m_Streams[s].stride - (int)(absoluteOffset % m_Streams[s].stride);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region compute FvF
|
#region compute FvF
|
||||||
|
@ -18,6 +18,7 @@ using System.Web.Script.Serialization;
|
|||||||
Load parent nodes even if they are not selected to provide transformations?
|
Load parent nodes even if they are not selected to provide transformations?
|
||||||
For extracting bundles, first check if file exists then decompress
|
For extracting bundles, first check if file exists then decompress
|
||||||
Double-check channelgroup argument in new FMOD Studio API system.playSound method
|
Double-check channelgroup argument in new FMOD Studio API system.playSound method
|
||||||
|
Font index error in Dreamfall Chapters
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Unity_Studio
|
namespace Unity_Studio
|
||||||
@ -33,7 +34,8 @@ namespace Unity_Studio
|
|||||||
//private AssetsFile mainDataFile = null;
|
//private AssetsFile mainDataFile = null;
|
||||||
private string mainPath = "";
|
private string mainPath = "";
|
||||||
private string productName = "";
|
private string productName = "";
|
||||||
|
private string[] fileTypes = new string[7] { "maindata.", "level*.", "*.assets", "*.sharedAssets", "CustomAssetBundle-*", "CAB-*", "BuildPlayer-*" };
|
||||||
|
|
||||||
Dictionary<string, Dictionary<string, string>> jsonMats;
|
Dictionary<string, Dictionary<string, string>> jsonMats;
|
||||||
Dictionary<string, SortedDictionary<int, ClassStrStruct>> AllClassStructures = new Dictionary<string, SortedDictionary<int, ClassStrStruct>>();
|
Dictionary<string, SortedDictionary<int, ClassStrStruct>> AllClassStructures = new Dictionary<string, SortedDictionary<int, ClassStrStruct>>();
|
||||||
|
|
||||||
@ -133,7 +135,6 @@ namespace Unity_Studio
|
|||||||
//TODO find a way to read data directly instead of merging files
|
//TODO find a way to read data directly instead of merging files
|
||||||
MergeSplitAssets(mainPath);
|
MergeSplitAssets(mainPath);
|
||||||
|
|
||||||
string[] fileTypes = new string[7] { "maindata.", "level*.", "*.assets", "*.sharedAssets", "CustomAssetBundle-*", "CAB-*", "BuildPlayer-*" };
|
|
||||||
for (int t = 0; t < fileTypes.Length; t++)
|
for (int t = 0; t < fileTypes.Length; t++)
|
||||||
{
|
{
|
||||||
string[] fileNames = Directory.GetFiles(mainPath, fileTypes[t], SearchOption.AllDirectories);
|
string[] fileNames = Directory.GetFiles(mainPath, fileTypes[t], SearchOption.AllDirectories);
|
||||||
@ -284,56 +285,60 @@ namespace Unity_Studio
|
|||||||
{
|
{
|
||||||
StatusStripUpdate("Decompressing " + Path.GetFileName(bundleFileName) + "...");
|
StatusStripUpdate("Decompressing " + Path.GetFileName(bundleFileName) + "...");
|
||||||
|
|
||||||
using (BundleFile b_File = new BundleFile(bundleFileName))
|
BundleFile b_File = new BundleFile(bundleFileName);
|
||||||
|
|
||||||
|
List<AssetsFile> b_assetsfileList = new List<AssetsFile>();
|
||||||
|
|
||||||
|
foreach (var memFile in b_File.MemoryAssetsFileList) //filter unity files
|
||||||
{
|
{
|
||||||
List<AssetsFile> b_assetsfileList = new List<AssetsFile>();
|
bool validAssetsFile = false;
|
||||||
|
switch (Path.GetExtension(memFile.fileName))
|
||||||
foreach (var memFile in b_File.MemoryAssetsFileList) //filter unity files
|
|
||||||
{
|
{
|
||||||
bool validAssetsFile = false;
|
case ".assets":
|
||||||
switch (Path.GetExtension(memFile.fileName))
|
case ".sharedAssets":
|
||||||
{
|
validAssetsFile = true;
|
||||||
case ".assets":
|
break;
|
||||||
case ".sharedAssets":
|
case "":
|
||||||
validAssetsFile = true;
|
validAssetsFile = (memFile.fileName == "mainData" ||
|
||||||
break;
|
Regex.IsMatch(memFile.fileName, "level.*?") ||
|
||||||
case "":
|
Regex.IsMatch(memFile.fileName, "CustomAssetBundle-.*?") ||
|
||||||
if (memFile.fileName == "mainData" || Regex.IsMatch(memFile.fileName, "level.*?") || Regex.IsMatch(memFile.fileName, "CustomAssetBundle-.*?") || Regex.IsMatch(memFile.fileName, "CAB-.*?") || Regex.IsMatch(memFile.fileName, "BuildPlayer-.*?")) { validAssetsFile = true; }
|
Regex.IsMatch(memFile.fileName, "CAB-.*?") ||
|
||||||
break;
|
Regex.IsMatch(memFile.fileName, "BuildPlayer-.*?"));
|
||||||
}
|
break;
|
||||||
|
|
||||||
if (validAssetsFile)
|
|
||||||
{
|
|
||||||
StatusStripUpdate("Loading " + memFile.fileName);
|
|
||||||
memFile.fileName = Path.GetDirectoryName(bundleFileName) + "\\" + memFile.fileName; //add path for extract location
|
|
||||||
|
|
||||||
AssetsFile assetsFile = new AssetsFile(memFile.fileName, new EndianStream(memFile.memStream, EndianType.BigEndian));
|
|
||||||
if (assetsFile.fileGen == 6 && Path.GetFileName(bundleFileName) != "mainData") //2.6.x and earlier don't have a string version before the preload table
|
|
||||||
{
|
|
||||||
//make use of the bundle file version
|
|
||||||
assetsFile.m_Version = b_File.ver3;
|
|
||||||
assetsFile.version = Array.ConvertAll((b_File.ver3.Split(new string[] { ".", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "\n" }, StringSplitOptions.RemoveEmptyEntries)), int.Parse);
|
|
||||||
assetsFile.buildType = b_File.ver3.Split(new string[] { ".", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
}
|
|
||||||
|
|
||||||
b_assetsfileList.Add(assetsFile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memFile.memStream.Close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assetsfileList.AddRange(b_assetsfileList);//will the streams still be available for reading data?
|
if (validAssetsFile)
|
||||||
|
|
||||||
foreach (var assetsFile in b_assetsfileList)
|
|
||||||
{
|
{
|
||||||
foreach (var sharedFile in assetsFile.sharedAssetsList)
|
StatusStripUpdate("Loading " + memFile.fileName);
|
||||||
|
//create dummy path to be used for asset extraction
|
||||||
|
memFile.fileName = Path.GetDirectoryName(bundleFileName) + "\\" + memFile.fileName;
|
||||||
|
|
||||||
|
AssetsFile assetsFile = new AssetsFile(memFile.fileName, new EndianStream(memFile.memStream, EndianType.BigEndian));
|
||||||
|
if (assetsFile.fileGen == 6 && Path.GetFileName(bundleFileName) != "mainData") //2.6.x and earlier don't have a string version before the preload table
|
||||||
{
|
{
|
||||||
sharedFile.fileName = Path.GetDirectoryName(bundleFileName) + "\\" + sharedFile.fileName;
|
//make use of the bundle file version
|
||||||
var loadedSharedFile = b_assetsfileList.Find(aFile => aFile.filePath == sharedFile.fileName);
|
assetsFile.m_Version = b_File.ver3;
|
||||||
if (loadedSharedFile != null) { sharedFile.Index = assetsfileList.IndexOf(loadedSharedFile); }
|
assetsFile.version = Array.ConvertAll((b_File.ver3.Split(new string[] { ".", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "\n" }, StringSplitOptions.RemoveEmptyEntries)), int.Parse);
|
||||||
|
assetsFile.buildType = b_File.ver3.Split(new string[] { ".", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b_assetsfileList.Add(assetsFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memFile.memStream.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assetsfileList.AddRange(b_assetsfileList);//will the streams still be available for reading data?
|
||||||
|
|
||||||
|
foreach (var assetsFile in b_assetsfileList)
|
||||||
|
{
|
||||||
|
foreach (var sharedFile in assetsFile.sharedAssetsList)
|
||||||
|
{
|
||||||
|
sharedFile.fileName = Path.GetDirectoryName(bundleFileName) + "\\" + sharedFile.fileName;
|
||||||
|
var loadedSharedFile = b_assetsfileList.Find(aFile => aFile.filePath == sharedFile.fileName);
|
||||||
|
if (loadedSharedFile != null) { sharedFile.Index = assetsfileList.IndexOf(loadedSharedFile); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -395,29 +400,29 @@ namespace Unity_Studio
|
|||||||
string extractPath = bundleFileName + "_unpacked\\";
|
string extractPath = bundleFileName + "_unpacked\\";
|
||||||
Directory.CreateDirectory(extractPath);
|
Directory.CreateDirectory(extractPath);
|
||||||
|
|
||||||
using (BundleFile b_File = new BundleFile(bundleFileName))
|
BundleFile b_File = new BundleFile(bundleFileName);
|
||||||
|
|
||||||
|
foreach (var memFile in b_File.MemoryAssetsFileList)
|
||||||
{
|
{
|
||||||
foreach (var memFile in b_File.MemoryAssetsFileList)
|
string filePath = extractPath + memFile.fileName.Replace('/', '\\');
|
||||||
|
if (!Directory.Exists(Path.GetDirectoryName(filePath)))
|
||||||
{
|
{
|
||||||
string filePath = extractPath + memFile.fileName.Replace('/','\\');
|
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
|
||||||
if (!Directory.Exists(Path.GetDirectoryName(filePath)))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (File.Exists(filePath))
|
if (File.Exists(filePath))
|
||||||
{
|
{
|
||||||
StatusStripUpdate("File " + memFile.fileName + " already exists");
|
StatusStripUpdate("File " + memFile.fileName + " already exists");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StatusStripUpdate("Extracting " + Path.GetFileName(memFile.fileName));
|
StatusStripUpdate("Extracting " + Path.GetFileName(memFile.fileName));
|
||||||
extractedCount += 1;
|
extractedCount += 1;
|
||||||
|
|
||||||
using (FileStream file = new FileStream(filePath, FileMode.Create, System.IO.FileAccess.Write))
|
using (FileStream file = new FileStream(filePath, FileMode.Create, System.IO.FileAccess.Write))
|
||||||
{
|
{
|
||||||
memFile.memStream.WriteTo(file);
|
memFile.memStream.WriteTo(file);
|
||||||
}
|
memFile.memStream.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1039,6 +1044,7 @@ namespace Unity_Studio
|
|||||||
{
|
{
|
||||||
if (firstSortColumn != e.Column)
|
if (firstSortColumn != e.Column)
|
||||||
{
|
{
|
||||||
|
//sorting column has been changed
|
||||||
reverseSort = false;
|
reverseSort = false;
|
||||||
secondSortColumn = firstSortColumn;
|
secondSortColumn = firstSortColumn;
|
||||||
}
|
}
|
||||||
@ -1074,6 +1080,7 @@ namespace Unity_Studio
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
assetListView.EndUpdate();
|
assetListView.EndUpdate();
|
||||||
|
|
||||||
resizeAssetListColumns();
|
resizeAssetListColumns();
|
||||||
@ -1859,6 +1866,11 @@ namespace Unity_Studio
|
|||||||
mb.AppendFormat("\n\t\t\tP: \"ShininessExponent\", \"Number\", \"\", \"A\",{0}", m_Float.second);
|
mb.AppendFormat("\n\t\t\tP: \"ShininessExponent\", \"Number\", \"\", \"A\",{0}", m_Float.second);
|
||||||
mb.AppendFormat("\n\t\t\tP: \"Shininess\", \"Number\", \"\", \"A\",{0}", m_Float.second);
|
mb.AppendFormat("\n\t\t\tP: \"Shininess\", \"Number\", \"\", \"A\",{0}", m_Float.second);
|
||||||
break;
|
break;
|
||||||
|
case "_Transparency":
|
||||||
|
mb.Append("\n\t\t\tP: \"TransparentColor\", \"Color\", \"\", \"A\",1,1,1");
|
||||||
|
mb.AppendFormat("\n\t\t\tP: \"TransparencyFactor\", \"Number\", \"\", \"A\",{0}", m_Float.second);
|
||||||
|
mb.AppendFormat("\n\t\t\tP: \"Opacity\", \"Number\", \"\", \"A\",{0}", (1 - m_Float.second));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
mb.AppendFormat("\n;\t\t\tP: \"{0}\", \"Number\", \"\", \"A\",{1}", m_Float.first, m_Float.second);
|
mb.AppendFormat("\n;\t\t\tP: \"{0}\", \"Number\", \"\", \"A\",{1}", m_Float.first, m_Float.second);
|
||||||
break;
|
break;
|
||||||
@ -1914,10 +1926,12 @@ namespace Unity_Studio
|
|||||||
cb2.Append("SpecularColor\"");
|
cb2.Append("SpecularColor\"");
|
||||||
break;
|
break;
|
||||||
case "_NormalMap":
|
case "_NormalMap":
|
||||||
case "_BumpMap":
|
|
||||||
case "gNormalSampler":
|
case "gNormalSampler":
|
||||||
cb2.Append("NormalMap\"");
|
cb2.Append("NormalMap\"");
|
||||||
break;
|
break;
|
||||||
|
case "_BumpMap":
|
||||||
|
cb2.Append("Bump\"");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
cb2.AppendFormat("{0}\"", m_TexEnv.name);
|
cb2.AppendFormat("{0}\"", m_TexEnv.name);
|
||||||
break;
|
break;
|
||||||
@ -2143,6 +2157,10 @@ namespace Unity_Studio
|
|||||||
AssetPreloadData MeshPD;
|
AssetPreloadData MeshPD;
|
||||||
if (assetsfileList.TryGetGameObject(m_SkinnedMeshRenderer.m_GameObject, out m_GameObject) && assetsfileList.TryGetPD(m_SkinnedMeshRenderer.m_Mesh, out MeshPD))
|
if (assetsfileList.TryGetGameObject(m_SkinnedMeshRenderer.m_GameObject, out m_GameObject) && assetsfileList.TryGetPD(m_SkinnedMeshRenderer.m_Mesh, out MeshPD))
|
||||||
{
|
{
|
||||||
|
//generate unique Geometry ID for instanced mesh objects
|
||||||
|
//I should find a way to preserve instances at least when exportDeformers is not selected
|
||||||
|
var keepID = MeshPD.uniqueID;
|
||||||
|
MeshPD.uniqueID = SkinnedMeshPD.uniqueID;
|
||||||
Mesh m_Mesh = new Mesh(MeshPD);
|
Mesh m_Mesh = new Mesh(MeshPD);
|
||||||
MeshFBX(m_Mesh, MeshPD.uniqueID, ob);
|
MeshFBX(m_Mesh, MeshPD.uniqueID, ob);
|
||||||
|
|
||||||
@ -2282,6 +2300,8 @@ namespace Unity_Studio
|
|||||||
bool stop = true;
|
bool stop = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MeshPD.uniqueID = keepID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user