mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-05-27 22:00:23 -04:00
Add split object fbx export to CLI
This commit is contained in:
parent
5ac597c935
commit
7cca301f7a
@ -13,6 +13,7 @@ namespace AssetStudioCLI
|
|||||||
public ClassIDType Type;
|
public ClassIDType Type;
|
||||||
public string Text;
|
public string Text;
|
||||||
public string UniqueID;
|
public string UniqueID;
|
||||||
|
public GameObjectNode Node;
|
||||||
|
|
||||||
public AssetItem(Object asset)
|
public AssetItem(Object asset)
|
||||||
{
|
{
|
||||||
|
16
AssetStudioCLI/Components/BaseNode.cs
Normal file
16
AssetStudioCLI/Components/BaseNode.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using AssetStudio;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AssetStudioCLI
|
||||||
|
{
|
||||||
|
internal class BaseNode
|
||||||
|
{
|
||||||
|
public List<BaseNode> nodes = new List<BaseNode>();
|
||||||
|
|
||||||
|
public BaseNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
16
AssetStudioCLI/Components/GameObjectNode.cs
Normal file
16
AssetStudioCLI/Components/GameObjectNode.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using AssetStudio;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AssetStudioCLI
|
||||||
|
{
|
||||||
|
internal class GameObjectNode : BaseNode
|
||||||
|
{
|
||||||
|
public GameObject gameObject;
|
||||||
|
|
||||||
|
public GameObjectNode(GameObject gameObject)
|
||||||
|
{
|
||||||
|
this.gameObject = gameObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
using AssetStudio;
|
using AssetStudio;
|
||||||
using AssetStudioCLI.Options;
|
using AssetStudioCLI.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -264,6 +265,34 @@ namespace AssetStudioCLI
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null)
|
||||||
|
{
|
||||||
|
var convert = animationList != null
|
||||||
|
? new ModelConverter(gameObject, CLIOptions.o_imageFormat.Value, animationList.Select(x => (AnimationClip)x.Asset).ToArray())
|
||||||
|
: new ModelConverter(gameObject, CLIOptions.o_imageFormat.Value);
|
||||||
|
exportPath = exportPath + FixFileName(gameObject.m_Name) + ".fbx";
|
||||||
|
ExportFbx(convert, exportPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ExportFbx(IImported convert, string exportPath)
|
||||||
|
{
|
||||||
|
var eulerFilter = true;
|
||||||
|
var filterPrecision = (float)0.25f;
|
||||||
|
var exportAllNodes = true;
|
||||||
|
var exportSkins = true;
|
||||||
|
var exportAnimations = true;
|
||||||
|
var exportBlendShape = true;
|
||||||
|
var castToBone = false;
|
||||||
|
var boneSize = CLIOptions.o_fbxBoneSize.Value;
|
||||||
|
var exportAllUvsAsDiffuseMaps = false;
|
||||||
|
var scaleFactor = CLIOptions.o_fbxScaleFactor.Value;
|
||||||
|
var fbxVersion = 3;
|
||||||
|
var fbxFormat = 0;
|
||||||
|
ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision,
|
||||||
|
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, fbxVersion, fbxFormat == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static bool ExportDumpFile(AssetItem item, string exportPath)
|
public static bool ExportDumpFile(AssetItem item, string exportPath)
|
||||||
{
|
{
|
||||||
if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath))
|
if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath))
|
||||||
|
@ -12,6 +12,7 @@ namespace AssetStudioCLI.Options
|
|||||||
General,
|
General,
|
||||||
Convert,
|
Convert,
|
||||||
Logger,
|
Logger,
|
||||||
|
FBX,
|
||||||
Advanced,
|
Advanced,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ namespace AssetStudioCLI.Options
|
|||||||
Dump,
|
Dump,
|
||||||
Info,
|
Info,
|
||||||
ExportLive2D,
|
ExportLive2D,
|
||||||
|
SplitObjects,
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum AssetGroupOption
|
internal enum AssetGroupOption
|
||||||
@ -79,6 +81,9 @@ namespace AssetStudioCLI.Options
|
|||||||
public static bool convertTexture;
|
public static bool convertTexture;
|
||||||
public static Option<ImageFormat> o_imageFormat;
|
public static Option<ImageFormat> o_imageFormat;
|
||||||
public static Option<AudioFormat> o_audioFormat;
|
public static Option<AudioFormat> o_audioFormat;
|
||||||
|
//fbx
|
||||||
|
public static Option<float> o_fbxScaleFactor;
|
||||||
|
public static Option<int> o_fbxBoneSize;
|
||||||
//advanced
|
//advanced
|
||||||
public static Option<ExportListType> o_exportAssetList;
|
public static Option<ExportListType> o_exportAssetList;
|
||||||
public static Option<List<string>> o_filterByName;
|
public static Option<List<string>> o_filterByName;
|
||||||
@ -158,6 +163,7 @@ namespace AssetStudioCLI.Options
|
|||||||
"Dump - Makes asset dumps\n" +
|
"Dump - Makes asset dumps\n" +
|
||||||
"Info - Loads file(s), shows the number of available for export assets and exits\n" +
|
"Info - Loads file(s), shows the number of available for export assets and exits\n" +
|
||||||
"Live2D - Exports Live2D Cubism 3 models\n" +
|
"Live2D - Exports Live2D Cubism 3 models\n" +
|
||||||
|
"SplitObjects - Export split objects\n" +
|
||||||
"Example: \"-m info\"\n",
|
"Example: \"-m info\"\n",
|
||||||
optionHelpGroup: HelpGroups.General
|
optionHelpGroup: HelpGroups.General
|
||||||
);
|
);
|
||||||
@ -249,6 +255,27 @@ namespace AssetStudioCLI.Options
|
|||||||
);
|
);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Init FBX Options
|
||||||
|
o_fbxScaleFactor = new GroupedOption<float>
|
||||||
|
(
|
||||||
|
optionDefaultValue: 1f,
|
||||||
|
optionName: "--fbx-scale-factor <value>",
|
||||||
|
optionDescription: "Specify the FBX Scale Factor\n" +
|
||||||
|
"<Value: float number from 0 to 100 (default=1)\n" +
|
||||||
|
"Example: \"--fbx-scale-factor 50\"\n",
|
||||||
|
optionHelpGroup: HelpGroups.FBX
|
||||||
|
);
|
||||||
|
o_fbxBoneSize = new GroupedOption<int>
|
||||||
|
(
|
||||||
|
optionDefaultValue: 10,
|
||||||
|
optionName: "--fbx-bone-size <value>",
|
||||||
|
optionDescription: "Specify the FBX Bone Size\n" +
|
||||||
|
"<Value: integer number from 0 to 100 (default=10)\n" +
|
||||||
|
"Example: \"--fbx-bone-size 10\"",
|
||||||
|
optionHelpGroup: HelpGroups.FBX
|
||||||
|
);
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Init Advanced Options
|
#region Init Advanced Options
|
||||||
o_exportAssetList = new GroupedOption<ExportListType>
|
o_exportAssetList = new GroupedOption<ExportListType>
|
||||||
(
|
(
|
||||||
@ -421,6 +448,19 @@ namespace AssetStudioCLI.Options
|
|||||||
ClassIDType.Transform,
|
ClassIDType.Transform,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
case "splitobjects":
|
||||||
|
o_workMode.Value = WorkMode.SplitObjects;
|
||||||
|
o_exportAssetTypes.Value = new List<ClassIDType>()
|
||||||
|
{
|
||||||
|
ClassIDType.GameObject,
|
||||||
|
ClassIDType.Texture2D,
|
||||||
|
ClassIDType.Material,
|
||||||
|
ClassIDType.Transform,
|
||||||
|
ClassIDType.Mesh,
|
||||||
|
ClassIDType.MeshRenderer,
|
||||||
|
ClassIDType.MeshFilter
|
||||||
|
};
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported working mode: [{value.Color(brightRed)}].\n");
|
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported working mode: [{value.Color(brightRed)}].\n");
|
||||||
Console.WriteLine(o_workMode.Description);
|
Console.WriteLine(o_workMode.Description);
|
||||||
@ -617,6 +657,32 @@ namespace AssetStudioCLI.Options
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "--fbx-scale-factor":
|
||||||
|
var isFloat = float.TryParse(value, out float floatValue);
|
||||||
|
if (isFloat && floatValue >= 0 && floatValue <= 100)
|
||||||
|
{
|
||||||
|
o_fbxScaleFactor.Value = floatValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported scale factor value: [{value.Color(brightRed)}].\n");
|
||||||
|
Console.WriteLine(o_fbxScaleFactor.Description);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "--fbx-bone-size":
|
||||||
|
var isInt = int.TryParse(value, out int intValue);
|
||||||
|
if (isInt && intValue >= 0 && intValue <= 100)
|
||||||
|
{
|
||||||
|
o_fbxBoneSize.Value = intValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{"Error".Color(brightRed)} during parsing [{option}] option. Unsupported bone size value: [{value.Color(brightRed)}].\n");
|
||||||
|
Console.WriteLine(o_fbxBoneSize.Description);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "--export-asset-list":
|
case "--export-asset-list":
|
||||||
switch (value.ToLower())
|
switch (value.ToLower())
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,9 @@ namespace AssetStudioCLI
|
|||||||
case WorkMode.ExportLive2D:
|
case WorkMode.ExportLive2D:
|
||||||
Studio.ExportLive2D();
|
Studio.ExportLive2D();
|
||||||
break;
|
break;
|
||||||
|
case WorkMode.SplitObjects:
|
||||||
|
Studio.ExportSplitObjects();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Studio.ExportAssets();
|
Studio.ExportAssets();
|
||||||
break;
|
break;
|
||||||
|
@ -24,6 +24,7 @@ General Options:
|
|||||||
Dump - Makes asset dumps
|
Dump - Makes asset dumps
|
||||||
Info - Loads file(s), shows the number of available for export assets and exits
|
Info - Loads file(s), shows the number of available for export assets and exits
|
||||||
Live2D - Exports Live2D Cubism 3 models
|
Live2D - Exports Live2D Cubism 3 models
|
||||||
|
SplitObjects - Export split objects
|
||||||
Example: "-m info"
|
Example: "-m info"
|
||||||
|
|
||||||
-t, --asset-type <value(s)> Specify asset type(s) to export
|
-t, --asset-type <value(s)> Specify asset type(s) to export
|
||||||
@ -67,6 +68,15 @@ Convert Options:
|
|||||||
None - Do not convert audios and export them in their own format
|
None - Do not convert audios and export them in their own format
|
||||||
Example: "--audio-format wav"
|
Example: "--audio-format wav"
|
||||||
|
|
||||||
|
FBX Options:
|
||||||
|
--fbx-scale-factor <value> Specify the FBX Scale Factor
|
||||||
|
<Value: float number from 0 to 100 (default=1)
|
||||||
|
Example: "--fbx-scale-factor 50"
|
||||||
|
|
||||||
|
--fbx-bone-size <value> Specify the FBX Bone Size
|
||||||
|
<Value: integer number from 0 to 100 (default=10)
|
||||||
|
Example: "--fbx-bone-size 10"
|
||||||
|
|
||||||
Advanced Options:
|
Advanced Options:
|
||||||
--export-asset-list <value> Specify the format in which you want to export asset list
|
--export-asset-list <value> Specify the format in which you want to export asset list
|
||||||
<Value: none(default) | xml>
|
<Value: none(default) | xml>
|
||||||
|
@ -15,6 +15,7 @@ namespace AssetStudioCLI
|
|||||||
{
|
{
|
||||||
public static AssetsManager assetsManager = new AssetsManager();
|
public static AssetsManager assetsManager = new AssetsManager();
|
||||||
public static List<AssetItem> parsedAssetsList = new List<AssetItem>();
|
public static List<AssetItem> parsedAssetsList = new List<AssetItem>();
|
||||||
|
public static List<BaseNode> gameObjectTree = new List<BaseNode>();
|
||||||
public static AssemblyLoader assemblyLoader = new AssemblyLoader();
|
public static AssemblyLoader assemblyLoader = new AssemblyLoader();
|
||||||
private static Dictionary<AssetStudio.Object, string> containers = new Dictionary<AssetStudio.Object, string>();
|
private static Dictionary<AssetStudio.Object, string> containers = new Dictionary<AssetStudio.Object, string>();
|
||||||
|
|
||||||
@ -53,6 +54,7 @@ namespace AssetStudioCLI
|
|||||||
|
|
||||||
var fileAssetsList = new List<AssetItem>();
|
var fileAssetsList = new List<AssetItem>();
|
||||||
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
|
||||||
|
var objectAssetItemDic = new Dictionary<AssetStudio.Object, AssetItem>(objectCount);
|
||||||
|
|
||||||
Progress.Reset();
|
Progress.Reset();
|
||||||
var i = 0;
|
var i = 0;
|
||||||
@ -61,6 +63,7 @@ namespace AssetStudioCLI
|
|||||||
foreach (var asset in assetsFile.Objects)
|
foreach (var asset in assetsFile.Objects)
|
||||||
{
|
{
|
||||||
var assetItem = new AssetItem(asset);
|
var assetItem = new AssetItem(asset);
|
||||||
|
objectAssetItemDic.Add(asset, assetItem);
|
||||||
assetItem.UniqueID = "_#" + i;
|
assetItem.UniqueID = "_#" + i;
|
||||||
var isExportable = false;
|
var isExportable = false;
|
||||||
switch (asset)
|
switch (asset)
|
||||||
@ -90,6 +93,9 @@ namespace AssetStudioCLI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GameObject m_GameObject:
|
||||||
|
assetItem.Text = m_GameObject.m_Name;
|
||||||
|
break;
|
||||||
case Texture2D m_Texture2D:
|
case Texture2D m_Texture2D:
|
||||||
if (!string.IsNullOrEmpty(m_Texture2D.m_StreamData?.path))
|
if (!string.IsNullOrEmpty(m_Texture2D.m_StreamData?.path))
|
||||||
assetItem.FullSize = asset.byteSize + m_Texture2D.m_StreamData.size;
|
assetItem.FullSize = asset.byteSize + m_Texture2D.m_StreamData.size;
|
||||||
@ -153,6 +159,12 @@ namespace AssetStudioCLI
|
|||||||
containers.Clear();
|
containers.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CLIOptions.o_workMode.Value == WorkMode.SplitObjects)
|
||||||
|
{
|
||||||
|
BuildTreeStructure(objectAssetItemDic);
|
||||||
|
}
|
||||||
|
|
||||||
var log = $"Finished loading {assetsManager.assetsFileList.Count} files with {parsedAssetsList.Count} exportable assets";
|
var log = $"Finished loading {assetsManager.assetsFileList.Count} files with {parsedAssetsList.Count} exportable assets";
|
||||||
var unityVer = assetsManager.assetsFileList[0].version;
|
var unityVer = assetsManager.assetsFileList[0].version;
|
||||||
long m_ObjectsCount;
|
long m_ObjectsCount;
|
||||||
@ -175,6 +187,93 @@ namespace AssetStudioCLI
|
|||||||
Logger.Info(log);
|
Logger.Info(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void BuildTreeStructure(Dictionary<AssetStudio.Object, AssetItem> objectAssetItemDic)
|
||||||
|
{
|
||||||
|
foreach (var entry in containers)
|
||||||
|
{
|
||||||
|
objectAssetItemDic[entry.Key].Container = entry.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
containers.Clear();
|
||||||
|
|
||||||
|
Logger.Info("Building tree structure...");
|
||||||
|
|
||||||
|
var treeNodeDictionary = new Dictionary<GameObject, GameObjectNode>();
|
||||||
|
var assetsFileCount = assetsManager.assetsFileList.Count;
|
||||||
|
int j = 0;
|
||||||
|
Progress.Reset();
|
||||||
|
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||||
|
{
|
||||||
|
var fileNode = new BaseNode();
|
||||||
|
|
||||||
|
foreach (var obj in assetsFile.Objects)
|
||||||
|
{
|
||||||
|
if (obj is GameObject m_GameObject)
|
||||||
|
{
|
||||||
|
if (!treeNodeDictionary.TryGetValue(m_GameObject, out var currentNode))
|
||||||
|
{
|
||||||
|
currentNode = new GameObjectNode(m_GameObject);
|
||||||
|
treeNodeDictionary.Add(m_GameObject, currentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var pptr in m_GameObject.m_Components)
|
||||||
|
{
|
||||||
|
if (pptr.TryGet(out var m_Component))
|
||||||
|
{
|
||||||
|
objectAssetItemDic[m_Component].Node = currentNode;
|
||||||
|
if (m_Component is MeshFilter m_MeshFilter)
|
||||||
|
{
|
||||||
|
if (m_MeshFilter.m_Mesh.TryGet(out var m_Mesh))
|
||||||
|
{
|
||||||
|
objectAssetItemDic[m_Mesh].Node = currentNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_Component is SkinnedMeshRenderer m_SkinnedMeshRenderer)
|
||||||
|
{
|
||||||
|
if (m_SkinnedMeshRenderer.m_Mesh.TryGet(out var m_Mesh))
|
||||||
|
{
|
||||||
|
objectAssetItemDic[m_Mesh].Node = currentNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var parentNode = fileNode;
|
||||||
|
|
||||||
|
if (m_GameObject.m_Transform != null)
|
||||||
|
{
|
||||||
|
if (m_GameObject.m_Transform.m_Father.TryGet(out var m_Father))
|
||||||
|
{
|
||||||
|
if (m_Father.m_GameObject.TryGet(out var parentGameObject))
|
||||||
|
{
|
||||||
|
if (!treeNodeDictionary.TryGetValue(parentGameObject, out var parentGameObjectNode))
|
||||||
|
{
|
||||||
|
parentGameObjectNode = new GameObjectNode(parentGameObject);
|
||||||
|
treeNodeDictionary.Add(parentGameObject, parentGameObjectNode);
|
||||||
|
}
|
||||||
|
parentNode = parentGameObjectNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parentNode.nodes.Add(currentNode);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileNode.nodes.Count > 0)
|
||||||
|
{
|
||||||
|
gameObjectTree.Add(fileNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
Progress.Report(++j, assetsFileCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
treeNodeDictionary.Clear();
|
||||||
|
|
||||||
|
objectAssetItemDic.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
public static void ShowExportableAssetsInfo()
|
public static void ShowExportableAssetsInfo()
|
||||||
{
|
{
|
||||||
var exportableAssetsCountDict = new Dictionary<ClassIDType, int>();
|
var exportableAssetsCountDict = new Dictionary<ClassIDType, int>();
|
||||||
@ -403,6 +502,67 @@ namespace AssetStudioCLI
|
|||||||
Logger.Info($"Finished exporting asset list with {parsedAssetsList.Count} items.");
|
Logger.Info($"Finished exporting asset list with {parsedAssetsList.Count} items.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ExportSplitObjects()
|
||||||
|
{
|
||||||
|
var savePath = CLIOptions.o_outputFolder.Value;
|
||||||
|
var count = parsedAssetsList.Count();
|
||||||
|
int k = 0;
|
||||||
|
Progress.Reset();
|
||||||
|
foreach (var node in gameObjectTree)
|
||||||
|
{
|
||||||
|
foreach(GameObjectNode j in node.nodes)
|
||||||
|
{
|
||||||
|
var gameObjects = new List<GameObject>();
|
||||||
|
CollectNode(j, gameObjects);
|
||||||
|
|
||||||
|
if (gameObjects.All(x => x.m_SkinnedMeshRenderer == null && x.m_MeshFilter == null))
|
||||||
|
{
|
||||||
|
Progress.Report(++k, count);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var filename = FixFileName(j.gameObject.m_Name);
|
||||||
|
var targetPath = $"{savePath}{filename}{Path.DirectorySeparatorChar}";
|
||||||
|
//重名文件处理
|
||||||
|
for (int i = 1; ; i++)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(targetPath))
|
||||||
|
{
|
||||||
|
targetPath = $"{savePath}{filename} ({i}){Path.DirectorySeparatorChar}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Directory.CreateDirectory(targetPath);
|
||||||
|
//导出FBX
|
||||||
|
Logger.Info($"Exporting {filename}.fbx");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ExportGameObject(j.gameObject, targetPath);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Error($"Export GameObject:{j.gameObject.m_Name} error", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Progress.Report(++k, count);
|
||||||
|
Logger.Info($"Finished exporting {filename}.fbx");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Logger.Info("Finished");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CollectNode(GameObjectNode node, List<GameObject> gameObjects)
|
||||||
|
{
|
||||||
|
gameObjects.Add(node.gameObject);
|
||||||
|
foreach (GameObjectNode i in node.nodes)
|
||||||
|
{
|
||||||
|
CollectNode(i, gameObjects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void ExportLive2D()
|
public static void ExportLive2D()
|
||||||
{
|
{
|
||||||
var baseDestPath = Path.Combine(CLIOptions.o_outputFolder.Value, "Live2DOutput");
|
var baseDestPath = Path.Combine(CLIOptions.o_outputFolder.Value, "Live2DOutput");
|
||||||
|
Loading…
Reference in New Issue
Block a user