Storyline+Dialog初步
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
#if ADDRESSABLES_INSTALLED
|
||||
using System.Collections.Generic;
|
||||
using SubAssetsToolbox.Editor;
|
||||
using UnityEditor.AddressableAssets;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SubAssetsToolbox.Utilities
|
||||
{
|
||||
internal static class AddressableEntryMigrator
|
||||
{
|
||||
internal static void MigrateOrRemoveEntry(string oldGuid, string parentGuid, string parentName)
|
||||
{
|
||||
AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
|
||||
if (settings == null) return;
|
||||
|
||||
AddressableAssetEntry oldEntry = settings.FindAssetEntry(oldGuid);
|
||||
if (oldEntry == null) return;
|
||||
|
||||
string oldName = oldEntry.MainAsset != null ? oldEntry.MainAsset.name : oldGuid;
|
||||
string address = oldEntry.address;
|
||||
AddressableAssetGroup group = oldEntry.parentGroup;
|
||||
HashSet<string> labels = new(oldEntry.labels);
|
||||
|
||||
AddressableAssetEntry parentEntry = settings.FindAssetEntry(parentGuid);
|
||||
|
||||
if (parentEntry != null)
|
||||
{
|
||||
// New host asset was already an Addressable, so the new sub-asset
|
||||
// is now addressable thanks to its parent – and the old entry can be removed.
|
||||
settings.RemoveAssetEntry(oldGuid);
|
||||
Debug.Log(string.Format(Constants.AddressableEntryRemoved, oldName, address, parentName));
|
||||
return;
|
||||
}
|
||||
|
||||
// The new host asset wasn't an Addressable, so the new host needs to become one
|
||||
settings.RemoveAssetEntry(oldGuid);
|
||||
AddressableAssetEntry newEntry = settings.CreateOrMoveEntry(parentGuid, group, false, false);
|
||||
newEntry.address = address;
|
||||
foreach (string label in labels)
|
||||
newEntry.SetLabel(label, true, true, false);
|
||||
settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, newEntry, true);
|
||||
|
||||
Debug.Log(string.Format(Constants.AddressableEntryMigrated, oldName, address, parentName));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2573a7e815d364c93b34c2a9efda007f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284154
|
||||
packageName: SubAssets Toolbox
|
||||
packageVersion: 1.1.0
|
||||
assetPath: Packages/io.continis.subassets/Editor/Utilities/AddressableEntryMigrator.cs
|
||||
uploadId: 869944
|
||||
@@ -0,0 +1,102 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using SubAssetsToolbox.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SubAssetsToolbox.Utilities
|
||||
{
|
||||
public static class AssetReferenceRedirector
|
||||
{
|
||||
public static bool RedirectToSubAsset(Object sourceAsset, Object destinationSubAsset)
|
||||
{
|
||||
string sourceFileID = GetFileID(sourceAsset);
|
||||
string destFileID = GetFileID(destinationSubAsset);
|
||||
if (sourceFileID == null || destFileID == null) return false;
|
||||
|
||||
string sourceGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(sourceAsset));
|
||||
string destGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(destinationSubAsset));
|
||||
|
||||
RedirectReferencesInYaml(sourceGuid, sourceFileID, destGuid, destFileID);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool RedirectToStandaloneAsset(Object sourceSubAsset, Object destinationAsset)
|
||||
{
|
||||
string sourceFileID = GetFileID(sourceSubAsset);
|
||||
string destFileID = GetFileID(destinationAsset);
|
||||
if (sourceFileID == null || destFileID == null) return false;
|
||||
|
||||
string sourceGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(sourceSubAsset));
|
||||
string destGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(destinationAsset));
|
||||
|
||||
RedirectReferencesInYaml(sourceGuid, sourceFileID, destGuid, destFileID);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void RedirectReferencesInYaml(string oldGuid, string oldFileID, string newGuid, string newFileID)
|
||||
{
|
||||
string[] extensions = SubAssetsToolboxSettings.PatchExtensions.value;
|
||||
string[] allFiles = Directory.GetFiles("Assets", "*.*", SearchOption.AllDirectories)
|
||||
.Where(f => extensions.Any(ext => f.EndsWith("." + ext)))
|
||||
.ToArray();
|
||||
|
||||
// Save and cache open scenes, if needed
|
||||
bool needToRestoreScenes = false;
|
||||
SceneSetup[] sceneManagerSetup = EditorSceneManager.GetSceneManagerSetup();
|
||||
string[] sceneFiles = allFiles.Where(f => f.EndsWith(".unity")).ToArray();
|
||||
if (sceneFiles.Length > 0)
|
||||
{
|
||||
needToRestoreScenes = sceneManagerSetup.Any(sceneSetup => sceneFiles.Any(f => f == sceneSetup.path));
|
||||
|
||||
if (needToRestoreScenes)
|
||||
{
|
||||
EditorSceneManager.SaveOpenScenes();
|
||||
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string filePath in allFiles)
|
||||
{
|
||||
string content = File.ReadAllText(filePath);
|
||||
if (!content.Contains(oldGuid)) continue;
|
||||
|
||||
string oldPattern = $"{{fileID: {oldFileID}, guid: {oldGuid}";
|
||||
string replacement = $"{{fileID: {newFileID}, guid: {newGuid}";
|
||||
|
||||
string newContent = content.Replace(oldPattern, replacement);
|
||||
|
||||
if (newContent == content) continue;
|
||||
|
||||
//Debug.Log($"Updated references in {filePath}");
|
||||
File.WriteAllText(filePath, newContent);
|
||||
}
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
if (needToRestoreScenes)
|
||||
EditorApplication.delayCall += () =>
|
||||
EditorSceneManager.RestoreSceneManagerSetup(sceneManagerSetup);
|
||||
}
|
||||
|
||||
static string GetFileID(Object obj)
|
||||
{
|
||||
long id = (long)Unsupported.GetLocalIdentifierInFileForPersistentObject(obj);
|
||||
if (id != 0) return id.ToString();
|
||||
|
||||
// Reflection fallback
|
||||
SerializedObject so = new(obj);
|
||||
PropertyInfo inspectorModeInfo = typeof(SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
inspectorModeInfo?.SetValue(so, InspectorMode.Debug, null);
|
||||
|
||||
SerializedProperty localIdProp = so.FindProperty("m_LocalIdentifierInFile");
|
||||
if (localIdProp != null && localIdProp.longValue != 0)
|
||||
return localIdProp.longValue.ToString();
|
||||
|
||||
Debug.LogError(string.Format(Constants.FileIdRetrievalFailed, obj.name));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e19698ca5817474fbc5e211dae150119
|
||||
timeCreated: 1770839624
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284154
|
||||
packageName: SubAssets Toolbox
|
||||
packageVersion: 1.1.0
|
||||
assetPath: Packages/io.continis.subassets/Editor/Utilities/AssetReferenceRedirector.cs
|
||||
uploadId: 869944
|
||||
64
Packages/io.continis.subassets/Editor/Utilities/Constants.cs
Normal file
64
Packages/io.continis.subassets/Editor/Utilities/Constants.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
namespace SubAssetsToolbox.Editor
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public const string MenuItemBaseName = "Tools/SubAssets Toolbox/";
|
||||
|
||||
// URLs
|
||||
public const string ReviewUrl = "https://assetstore.unity.com/packages/tools/utilities/subassets-toolbox-284154#reviews";
|
||||
public const string DiscordUrl = "https://discord.com/invite/rCRug7Szr8";
|
||||
public const string DocumentationUrl = "https://tools.continis.io/v/subassets-toolbox";
|
||||
public const string OtherToolsUrl = "https://assetstore.unity.com/publishers/87819";
|
||||
public const string SupportEmail = "mailto:buoybase@gmail.com";
|
||||
|
||||
public const string PackageName = "io.continis.subassets-toolbox";
|
||||
public const string PackageAssetsFolder = "Packages/io.continis.subassets-toolbox";
|
||||
public const string PackageReadableName = "SubAssets Toolbox";
|
||||
|
||||
// Error messages - Sub-asset type restrictions
|
||||
internal static readonly string AddingPrefabAsSubAsset = $"({PackageReadableName}) Adding a Prefab as a SubAsset is not allowed.";
|
||||
internal static readonly string AddingFolderAsSubAsset = $"({PackageReadableName}) Adding a Folder as a SubAsset is not allowed.";
|
||||
internal static readonly string AddingScriptAsSubAsset = $"({PackageReadableName}) Adding a script as a SubAsset is not allowed.";
|
||||
internal static readonly string Adding3DModelAsSubAsset = $"({PackageReadableName}) Adding a 3D model as a SubAsset is not allowed.";
|
||||
internal static readonly string AddingShaderAsSubAsset = $"({PackageReadableName}) Adding a shader as a SubAsset is not allowed.";
|
||||
|
||||
// Error messages - Destination type restrictions
|
||||
internal static readonly string AddingSubAssetToScript = $"({PackageReadableName}) Adding SubAssets to a script is not allowed.";
|
||||
internal static readonly string AddingSubAssetToShader = $"({PackageReadableName}) Adding SubAssets to a Shader is not allowed.";
|
||||
internal static readonly string AddingSubAssetTo3DModel = $"({PackageReadableName}) Adding SubAssets to a 3D model is not allowed.";
|
||||
internal static readonly string AddingSubAssetToMixer = $"({PackageReadableName}) Adding SubAssets to an AudioMixer is not allowed.";
|
||||
internal static readonly string AddingSubAssetToScene = $"({PackageReadableName}) Adding SubAssets to a scene is not allowed.";
|
||||
|
||||
// Warnings
|
||||
internal static readonly string ExtensionDefaultedToAsset = $"({PackageReadableName}) It was impossible to determine the removed sub-assets extension, so it has defaulted to \".asset\". " +
|
||||
"We recommend to change it now in your file system, if it matters.";
|
||||
|
||||
internal static readonly string ImpossibleToExtract =
|
||||
$"({PackageReadableName}) Impossible to extract {{0}} from its main asset. An asset with the same name already exists in the same location.";
|
||||
internal static readonly string RedirectionFailed = $"({PackageReadableName}) Reference patching failed for {{0}}. The original asset was kept to avoid broken references.";
|
||||
internal static readonly string FileIdRetrievalFailed = $"({PackageReadableName}) Could not retrieve fileID for {{0}}. Reference redirection skipped for this object.";
|
||||
|
||||
// Dialog messages
|
||||
internal const string LossOfDataWarning = "If you choose not to, you will have to " +
|
||||
"fix those references manually.\n\n" +
|
||||
"This process might lead to loss of data, " +
|
||||
"so make sure you have your project under version control.";
|
||||
|
||||
internal const string ConfirmAddAsSubAsset = "Are you sure you want to add {0} as a sub-asset to {1}?";
|
||||
internal const string ConfirmAddAsSubAssets = "Are you sure you want to add {0}, {1}, (...) as sub-assets to {2}?";
|
||||
|
||||
internal const string ConfirmDeleteSubAsset = "Are you sure you want to delete {0}?";
|
||||
internal const string ConfirmDeleteSubAssets = "Are you sure you want to delete {0}, {1}, (...)?";
|
||||
|
||||
internal const string PatchRefsToSubAssetPrompt =
|
||||
"Do you want to patch all references to the dragged asset(s) to point to the newly-created sub-asset(s)? " + LossOfDataWarning;
|
||||
internal const string PatchRefsToStandalonePrompt =
|
||||
"Do you want to patch all references to the dragged sub-asset(s) to point to the newly-created asset(s)? " + LossOfDataWarning;
|
||||
|
||||
// Addressable messages
|
||||
internal static readonly string AddressableEntryMigrated =
|
||||
$"({PackageReadableName}) Addressable entry '{{0}}' (address: {{1}}) was migrated to the parent asset {{2}}.";
|
||||
internal static readonly string AddressableEntryRemoved =
|
||||
$"({PackageReadableName}) Addressable entry '{{0}}' (address: {{1}}) was removed. The parent asset {{2}} is already Addressable.";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ebbd0fca8514146f8bcbc90035ba23d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284154
|
||||
packageName: SubAssets Toolbox
|
||||
packageVersion: 1.1.0
|
||||
assetPath: Packages/io.continis.subassets/Editor/Utilities/Constants.cs
|
||||
uploadId: 869944
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SubAssetsToolbox.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Animations;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Audio;
|
||||
using UnityEngine.U2D;
|
||||
|
||||
namespace SubAssetsToolbox.Utilities
|
||||
{
|
||||
public static class ExtensionMap
|
||||
{
|
||||
public static string GetFileExtensionByType(Type t)
|
||||
{
|
||||
if (_extensions.TryGetValue(t, out string ext))
|
||||
return ext;
|
||||
else
|
||||
{
|
||||
if(!typeof(ScriptableObject).IsAssignableFrom(t))
|
||||
Debug.LogWarning(Constants.ExtensionDefaultedToAsset);
|
||||
|
||||
return "asset";
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Dictionary<Type, string> _extensions = new()
|
||||
{
|
||||
// Rendering / Shaders
|
||||
{ typeof(Material), "mat" },
|
||||
{ typeof(Shader), "shader" },
|
||||
{ typeof(ComputeShader), "compute" },
|
||||
{ typeof(ShaderVariantCollection), "shadervariants" },
|
||||
{ typeof(LightmapParameters), "giparams" },
|
||||
{ typeof(LightingSettings), "lighting" },
|
||||
|
||||
// Animation
|
||||
{ typeof(AnimationClip), "anim" },
|
||||
{ typeof(AnimatorController), "controller" },
|
||||
{ typeof(AnimatorOverrideController), "overrideController" },
|
||||
{ typeof(AvatarMask), "mask" },
|
||||
{ typeof(Avatar), "avatar" },
|
||||
|
||||
// Physics
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
{ typeof(PhysicsMaterial), "physicsMaterial" },
|
||||
#else
|
||||
{ typeof(PhysicMaterial), "physicMaterial" },
|
||||
#endif
|
||||
{ typeof(PhysicsMaterial2D), "physicsMaterial2D" },
|
||||
|
||||
// Audio
|
||||
{ typeof(AudioMixer), "mixer" },
|
||||
|
||||
// 2D
|
||||
{ typeof(SpriteAtlas), "spriteatlas" },
|
||||
|
||||
// Textures
|
||||
{ typeof(Cubemap), "cubemap" },
|
||||
{ typeof(RenderTexture), "rendertexture" },
|
||||
|
||||
// 3D
|
||||
{ typeof(Mesh), "mesh" },
|
||||
{ typeof(TerrainLayer), "terrainlayer" },
|
||||
|
||||
// GUI
|
||||
{ typeof(Font), "fontsettings" },
|
||||
{ typeof(GUISkin), "guiskin" },
|
||||
|
||||
// Effects
|
||||
{ typeof(Flare), "flare" },
|
||||
{ typeof(LightingDataAsset), "lighting" }
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3732dc6b75842c8a5d9f63611840216
|
||||
timeCreated: 1757267868
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284154
|
||||
packageName: SubAssets Toolbox
|
||||
packageVersion: 1.1.0
|
||||
assetPath: Packages/io.continis.subassets/Editor/Utilities/ExtensionMap.cs
|
||||
uploadId: 869944
|
||||
130
Packages/io.continis.subassets/Editor/Utilities/TypeChecker.cs
Normal file
130
Packages/io.continis.subassets/Editor/Utilities/TypeChecker.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SubAssetsToolbox.Editor
|
||||
{
|
||||
public static class TypeChecker
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if a path contains a type that can be made into a sub-asset
|
||||
/// </summary>
|
||||
public static bool ValidateSubAssetType(string path, bool silent = false)
|
||||
{
|
||||
if (AssetDatabase.IsValidFolder(path))
|
||||
{
|
||||
if (!silent) Debug.LogError(Constants.AddingFolderAsSubAsset);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (path.EndsWith(".prefab"))
|
||||
{
|
||||
if (!silent) Debug.LogError(Constants.AddingPrefabAsSubAsset);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (path.EndsWith(".cs"))
|
||||
{
|
||||
if (!silent) Debug.LogError(Constants.AddingScriptAsSubAsset);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsShader(path))
|
||||
{
|
||||
if (!silent) Debug.LogError(Constants.AddingShaderAsSubAsset);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Is3DModel(path))
|
||||
{
|
||||
if (!silent) Debug.LogError(Constants.Adding3DModelAsSubAsset);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (path.EndsWith(".meta"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a path contains a type that can accept sub-assets
|
||||
/// </summary>
|
||||
public static bool ValidateDestinationType(string destinationPath, bool silent = false)
|
||||
{
|
||||
if (destinationPath.EndsWith(".cs"))
|
||||
{
|
||||
if (!silent) Debug.LogError(Constants.AddingSubAssetToScript);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (destinationPath.EndsWith(".unity"))
|
||||
{
|
||||
if (!silent) Debug.LogError(Constants.AddingSubAssetToScene);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsShader(destinationPath))
|
||||
{
|
||||
if (!silent) Debug.LogError(Constants.AddingSubAssetToShader);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Is3DModel(destinationPath))
|
||||
{
|
||||
if (!silent) Debug.LogError(Constants.AddingSubAssetTo3DModel);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (destinationPath.EndsWith(".mixer"))
|
||||
{
|
||||
if (!silent) Debug.LogError(Constants.AddingSubAssetToMixer);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (destinationPath.EndsWith(".meta"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a path contains a type where the right-click is already doing something else
|
||||
/// i.e. when right-clicking on a Shader and creating a Material, it should create a Material
|
||||
/// with that Shader and not a Material as a sub-object of a Shader.
|
||||
/// </summary>
|
||||
public static bool HasDefaultAction(string newObjectPath, string destinationPath)
|
||||
{
|
||||
// Prefab variants
|
||||
if (newObjectPath.EndsWith(".prefab") && destinationPath.EndsWith(".prefab"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Variant of a 3D model
|
||||
bool destinationIs3DModel = Is3DModel(destinationPath);
|
||||
if (newObjectPath.EndsWith(".prefab") && destinationIs3DModel)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Material from shader
|
||||
bool destinationIsShader = IsShader(destinationPath);
|
||||
if (newObjectPath.EndsWith(".mat") && destinationIsShader)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsShader(string path) => path.EndsWith(".shader") || path.EndsWith(".shadergraph");
|
||||
|
||||
private static bool Is3DModel(string path) =>
|
||||
path.EndsWith(".fbx") || path.EndsWith(".blend") ||
|
||||
path.EndsWith(".obj") || path.EndsWith(".3ds");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e015603f942f4b20bafb85236f2ac50d
|
||||
timeCreated: 1741992985
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 284154
|
||||
packageName: SubAssets Toolbox
|
||||
packageVersion: 1.1.0
|
||||
assetPath: Packages/io.continis.subassets/Editor/Utilities/TypeChecker.cs
|
||||
uploadId: 869944
|
||||
Reference in New Issue
Block a user