+Add : Blocking test & Cleanup
This commit is contained in:
@@ -14,10 +14,8 @@ namespace FBXImporter
|
||||
/// 4. Force reimport
|
||||
/// 5. Connect PBR textures → create .mat files
|
||||
/// 6. Extract animation clips → Animations/
|
||||
/// 7. Generate prefab
|
||||
/// 7. Generate prefab(s) — one per mesh if multi-mesh FBX
|
||||
/// 8. Create AnimatorController + assign to prefab
|
||||
/// 9. Delete Sources/Materials/ (Unity auto-generates it, we don't need it)
|
||||
/// 10. Delete original source folder (cleanup)
|
||||
/// </summary>
|
||||
public static void Process(string fbxAssetPath,
|
||||
ModelImporterAnimationType animationType = ModelImporterAnimationType.Generic,
|
||||
@@ -33,8 +31,8 @@ namespace FBXImporter
|
||||
|
||||
Debug.Log($"[FBXImporter] ── Processing {Path.GetFileName(fbxAssetPath)} ──");
|
||||
|
||||
var source = FBXSourceDetector.Detect(fbxAssetPath);
|
||||
var folders = FolderSetup.Resolve(fbxAssetPath);
|
||||
var source = FBXSourceDetector.Detect(fbxAssetPath);
|
||||
var folders = FolderSetup.Resolve(fbxAssetPath);
|
||||
bool withAnims = animationType != ModelImporterAnimationType.None;
|
||||
|
||||
FolderSetup.Create(
|
||||
@@ -67,10 +65,10 @@ namespace FBXImporter
|
||||
if (withAnims && !string.IsNullOrEmpty(folders.Animations))
|
||||
AnimationExtractor.ExtractClips(fbxAssetPath, folders.Animations);
|
||||
|
||||
// Generate prefab
|
||||
// Generate prefab(s)
|
||||
string assetName = Path.GetFileNameWithoutExtension(fbxAssetPath);
|
||||
string prefabPath = $"{folders.Prefabs}/{assetName}.prefab";
|
||||
PrefabBuilder.CreatePrefab(fbxAsset, folders.Prefabs, assetName);
|
||||
PrefabBuilder.CreatePrefabs(fbxAsset, folders, assetName);
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
@@ -79,28 +77,9 @@ namespace FBXImporter
|
||||
if (withAnims && !string.IsNullOrEmpty(folders.Animations))
|
||||
AnimatorControllerBuilder.CreateAndAssign(folders.Animations, prefabPath, assetName);
|
||||
|
||||
// Delete Sources/Materials/ — Unity creates it automatically but we use
|
||||
// the root Materials/ folder instead, so this one is redundant
|
||||
string sourceMaterialsPath = $"{folders.Sources}/Materials";
|
||||
if (AssetDatabase.IsValidFolder(sourceMaterialsPath))
|
||||
{
|
||||
AssetDatabase.DeleteAsset(sourceMaterialsPath);
|
||||
Debug.Log($"[FBXImporter] Deleted Sources/Materials/ (using root Materials/ instead)");
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
// Cleanup original source folder if provided and different from our Sources/
|
||||
if (!string.IsNullOrEmpty(originalSourceFolder) &&
|
||||
originalSourceFolder != folders.Sources &&
|
||||
originalSourceFolder != folders.Root &&
|
||||
AssetDatabase.IsValidFolder(originalSourceFolder))
|
||||
{
|
||||
AssetDatabase.DeleteAsset(originalSourceFolder);
|
||||
Debug.Log($"[FBXImporter] Deleted original folder: {originalSourceFolder}");
|
||||
}
|
||||
|
||||
Debug.Log($"[FBXImporter] ── Done: {assetName} ──");
|
||||
}
|
||||
|
||||
@@ -121,7 +100,7 @@ namespace FBXImporter
|
||||
importer.materialImportMode = ModelImporterMaterialImportMode.ImportViaMaterialDescription;
|
||||
importer.materialLocation = ModelImporterMaterialLocation.External;
|
||||
importer.materialName = ModelImporterMaterialName.BasedOnMaterialName;
|
||||
importer.materialSearch = ModelImporterMaterialSearch.RecursiveUp;
|
||||
importer.materialSearch = ModelImporterMaterialSearch.Local;
|
||||
|
||||
importer.animationType = animType;
|
||||
if (!string.IsNullOrWhiteSpace(rootNode))
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace FBXImporter
|
||||
{
|
||||
public static class PrefabBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a single prefab from the imported FBX root GameObject.
|
||||
/// Adds a LODGroup automatically if _LOD0, _LOD1... meshes are found.
|
||||
/// </summary>
|
||||
public static void CreatePrefabs(GameObject fbxRoot, AssetFolders folders, string assetName)
|
||||
{
|
||||
CreateSinglePrefab(fbxRoot, folders.Prefabs, assetName);
|
||||
}
|
||||
|
||||
public static GameObject CreatePrefab(GameObject fbxRoot, string prefabDir, string assetName)
|
||||
{
|
||||
if (fbxRoot == null) return null;
|
||||
return CreateSinglePrefab(fbxRoot, prefabDir, assetName);
|
||||
}
|
||||
|
||||
if (!AssetDatabase.IsValidFolder(prefabDir))
|
||||
{
|
||||
string parent = System.IO.Path.GetDirectoryName(prefabDir).Replace("\\", "/");
|
||||
AssetDatabase.CreateFolder(parent, System.IO.Path.GetFileName(prefabDir));
|
||||
}
|
||||
static GameObject CreateSinglePrefab(GameObject fbxRoot, string prefabDir, string assetName)
|
||||
{
|
||||
EnsureFolder(prefabDir);
|
||||
|
||||
var instance = Object.Instantiate(fbxRoot);
|
||||
instance.name = assetName;
|
||||
@@ -68,5 +77,14 @@ namespace FBXImporter
|
||||
if (idx < 0) return -1;
|
||||
return int.TryParse(name.Substring(idx + 4), out int level) ? level : -1;
|
||||
}
|
||||
|
||||
static void EnsureFolder(string path)
|
||||
{
|
||||
if (AssetDatabase.IsValidFolder(path)) return;
|
||||
string parent = Path.GetDirectoryName(path).Replace("\\", "/");
|
||||
string child = Path.GetFileName(path);
|
||||
if (!AssetDatabase.IsValidFolder(parent)) EnsureFolder(parent);
|
||||
AssetDatabase.CreateFolder(parent, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,34 @@ namespace FBXImporter
|
||||
/// Persistent registry of FBX files seen by the importer.
|
||||
/// Stores GUID + filename so the file is human-readable.
|
||||
/// Format per line: "guid TAB filename.fbx"
|
||||
/// Registry file is stored next to this script, wherever the plugin is installed.
|
||||
/// </summary>
|
||||
public static class ProcessedFBXRegistry
|
||||
{
|
||||
static readonly string RegistryPath = "Assets/Scripts/Editor/FBXImporter/processed_fbx.txt";
|
||||
// Resolved dynamically so the registry follows the plugin wherever it's installed
|
||||
static string _registryPath;
|
||||
static string RegistryPath
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_registryPath != null) return _registryPath;
|
||||
|
||||
var guids = AssetDatabase.FindAssets("ProcessedFBXRegistry t:Script");
|
||||
foreach (var guid in guids)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
if (path.Contains("FBXImporter"))
|
||||
{
|
||||
_registryPath = Path.GetDirectoryName(path).Replace("\\", "/") + "/processed_fbx.txt";
|
||||
return _registryPath;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback — should never happen if plugin is properly installed
|
||||
_registryPath = "Assets/processed_fbx.txt";
|
||||
return _registryPath;
|
||||
}
|
||||
}
|
||||
|
||||
// guid → filename (for display)
|
||||
static Dictionary<string, string> _registry;
|
||||
@@ -28,7 +52,7 @@ namespace FBXImporter
|
||||
return !string.IsNullOrEmpty(guid) && Registry.ContainsKey(guid);
|
||||
}
|
||||
|
||||
public static void Register(IEnumerable<string> assetPaths)
|
||||
public static void Register(System.Collections.Generic.IEnumerable<string> assetPaths)
|
||||
{
|
||||
bool changed = false;
|
||||
foreach (var path in assetPaths)
|
||||
@@ -95,8 +119,7 @@ namespace FBXImporter
|
||||
var lines = Registry.Select(kvp => $"{kvp.Key}\t{kvp.Value}").ToArray();
|
||||
File.WriteAllLines(RegistryPath, lines);
|
||||
|
||||
// Nullify cache so the next access reloads from disk.
|
||||
// This prevents stale in-memory state after domain reloads.
|
||||
// Nullify cache so the next access reloads from disk
|
||||
_registry = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FBXImporter
|
||||
{
|
||||
public class FBXDropWatcher : AssetPostprocessor
|
||||
{
|
||||
static readonly List<string> _pendingNewFBX = new List<string>();
|
||||
static bool _dialogScheduled = false;
|
||||
|
||||
bool ShouldWatch()
|
||||
{
|
||||
return assetPath.StartsWith("Assets/")
|
||||
&& assetPath.EndsWith(".fbx", System.StringComparison.OrdinalIgnoreCase)
|
||||
&& !ProcessedFBXRegistry.IsRegistered(assetPath);
|
||||
}
|
||||
|
||||
void OnPreprocessModel()
|
||||
{
|
||||
if (!ShouldWatch()) return;
|
||||
|
||||
var importer = assetImporter as ModelImporter;
|
||||
importer.importCameras = false;
|
||||
importer.importLights = false;
|
||||
importer.importNormals = ModelImporterNormals.Import;
|
||||
importer.importTangents = ModelImporterTangents.CalculateMikk;
|
||||
importer.importBlendShapes = true;
|
||||
importer.importVisibility = true;
|
||||
importer.materialImportMode = ModelImporterMaterialImportMode.ImportViaMaterialDescription;
|
||||
importer.materialLocation = ModelImporterMaterialLocation.External;
|
||||
importer.materialName = ModelImporterMaterialName.BasedOnMaterialName;
|
||||
importer.materialSearch = ModelImporterMaterialSearch.RecursiveUp;
|
||||
importer.useFileScale = true;
|
||||
importer.globalScale = 1f;
|
||||
}
|
||||
|
||||
void OnPostprocessModel(UnityEngine.GameObject root)
|
||||
{
|
||||
if (!ShouldWatch()) return;
|
||||
|
||||
if (!_pendingNewFBX.Contains(assetPath))
|
||||
_pendingNewFBX.Add(assetPath);
|
||||
|
||||
if (!_dialogScheduled)
|
||||
{
|
||||
_dialogScheduled = true;
|
||||
EditorApplication.delayCall += ShowBatchDialog;
|
||||
}
|
||||
}
|
||||
|
||||
static void ShowBatchDialog()
|
||||
{
|
||||
_dialogScheduled = false;
|
||||
if (_pendingNewFBX.Count == 0) return;
|
||||
|
||||
var batch = new List<string>(_pendingNewFBX);
|
||||
_pendingNewFBX.Clear();
|
||||
|
||||
// Register all immediately — won't appear again regardless of user choice
|
||||
ProcessedFBXRegistry.Register(batch);
|
||||
|
||||
FBXBatchDialog.Show(batch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b0ef00f525fdd4498665e9164696f58
|
||||
@@ -27,7 +27,6 @@ namespace FBXImporter
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
minSize = new Vector2(450, 650);
|
||||
GUILayout.Label("FBX Importer", EditorStyles.boldLabel);
|
||||
EditorGUILayout.HelpBox(
|
||||
"Select a .fbx in the Project panel.\n" +
|
||||
|
||||
Reference in New Issue
Block a user