(Feat) Add Build
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Ashwild.Building;
|
||||
using FishNet.Object;
|
||||
|
||||
namespace Ashwild.EditorTools
|
||||
{
|
||||
/// <summary>
|
||||
/// One-shot migration for the move to server-spawned builds: every committed structure is now a real
|
||||
/// NetworkObject, so each buildable's BuiltPrefab needs a NetworkObject and a BuiltStructure on its
|
||||
/// root. Prefabs authored before that change have neither (or only BuiltStructure, which is now a
|
||||
/// NetworkBehaviour and cannot function alone), and a missing NetworkObject makes the prefab silently
|
||||
/// unspawnable — the exact failure that used to leave a placed chest deactivated.
|
||||
///
|
||||
/// Safe to re-run: it only touches prefabs that are actually missing a component, and reports what it
|
||||
/// changed. Kept as an explicit menu action rather than an automatic postprocessor because it rewrites
|
||||
/// authored assets, which should never happen behind the designer's back.
|
||||
/// </summary>
|
||||
public static class BuiltPrefabMigrator
|
||||
{
|
||||
#region Menu
|
||||
|
||||
/// <summary>
|
||||
/// Scans every BuildableData, ensures its BuiltPrefab carries NetworkObject + BuiltStructure, and
|
||||
/// asks FishNet to rescan its spawnable prefab collection afterwards.
|
||||
/// </summary>
|
||||
[MenuItem("Tools/Ashwild/Migrate Built Prefabs To Network Objects")]
|
||||
public static void Migrate()
|
||||
{
|
||||
string[] guids = AssetDatabase.FindAssets("t:BuildableData");
|
||||
int migrated = 0;
|
||||
int alreadyFine = 0;
|
||||
int missingPrefab = 0;
|
||||
|
||||
foreach (string guid in guids)
|
||||
{
|
||||
BuildableData buildable = AssetDatabase.LoadAssetAtPath<BuildableData>(AssetDatabase.GUIDToAssetPath(guid));
|
||||
if (buildable == null) continue;
|
||||
|
||||
if (buildable.BuiltPrefab == null)
|
||||
{
|
||||
Debug.LogWarning($"[BuiltPrefabMigrator] '{buildable.name}' has no BuiltPrefab — skipped.", buildable);
|
||||
missingPrefab++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (EnsureNetworked(buildable.BuiltPrefab)) migrated++;
|
||||
else alreadyFine++;
|
||||
}
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
RefreshNetworkPrefabRegistry();
|
||||
|
||||
Debug.Log($"[BuiltPrefabMigrator] Done — {migrated} prefab(s) migrated, {alreadyFine} already correct, {missingPrefab} buildable(s) without a BuiltPrefab.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Adds whatever the prefab root is missing and saves it. The NetworkObject goes on first so that
|
||||
/// BuiltStructure's RequireComponent is already satisfied when it is added. Returns true when the
|
||||
/// prefab was actually changed.
|
||||
/// </summary>
|
||||
private static bool EnsureNetworked(GameObject prefab)
|
||||
{
|
||||
string path = AssetDatabase.GetAssetPath(prefab);
|
||||
if (string.IsNullOrEmpty(path)) return false;
|
||||
|
||||
GameObject root = PrefabUtility.LoadPrefabContents(path);
|
||||
bool changed = false;
|
||||
|
||||
if (root.GetComponent<NetworkObject>() == null)
|
||||
{
|
||||
root.AddComponent<NetworkObject>();
|
||||
changed = true;
|
||||
}
|
||||
if (root.GetComponent<BuiltStructure>() == null)
|
||||
{
|
||||
root.AddComponent<BuiltStructure>();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
PrefabUtility.SaveAsPrefabAsset(root, path);
|
||||
Debug.Log($"[BuiltPrefabMigrator] Migrated '{path}'.", AssetDatabase.LoadAssetAtPath<GameObject>(path));
|
||||
}
|
||||
|
||||
PrefabUtility.UnloadPrefabContents(root);
|
||||
return changed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces FishNet to rescan DefaultPrefabObjects so the migrated prefabs are spawnable. Invoked
|
||||
/// through the menu item because the generator API is internal to the FishNet assembly.
|
||||
/// </summary>
|
||||
private static void RefreshNetworkPrefabRegistry()
|
||||
{
|
||||
const string menu = "Tools/Fish-Networking/Utility/Refresh Default Prefabs";
|
||||
if (!EditorApplication.ExecuteMenuItem(menu))
|
||||
Debug.LogWarning($"[BuiltPrefabMigrator] Could not run '{menu}' — run it by hand so the built prefabs are registered as spawnable.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user