227 lines
8.6 KiB
C#
227 lines
8.6 KiB
C#
using UnityEditor.AddressableAssets;
|
|
using UnityEditor.AddressableAssets.Settings;
|
|
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
|
|
namespace AppleHills.Editor.Utilities
|
|
{
|
|
/// <summary>
|
|
/// Utility methods for working with the Addressables system in editor scripts.
|
|
/// Contains common operations for creating and managing groups and entries.
|
|
/// </summary>
|
|
public static class AddressablesUtility
|
|
{
|
|
/// <summary>
|
|
/// Get or create the Addressables settings. Returns null if Addressables are not properly set up.
|
|
/// </summary>
|
|
/// <param name="createIfMissing">If true, will attempt to create settings if they don't exist</param>
|
|
/// <returns>The AddressableAssetSettings or null if not available</returns>
|
|
public static AddressableAssetSettings GetAddressableSettings(bool createIfMissing = false)
|
|
{
|
|
var settings = AddressableAssetSettingsDefaultObject.GetSettings(createIfMissing);
|
|
if (settings == null && createIfMissing)
|
|
{
|
|
Debug.LogError("AddressableAssetSettings could not be found or created. Please ensure Addressables are set up in your project.");
|
|
}
|
|
return settings;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve or create an Addressables group.
|
|
/// </summary>
|
|
/// <param name="name">Name of the group</param>
|
|
/// <param name="includeInBuild">Whether to include assets in this group when building</param>
|
|
/// <returns>The created or existing group, or null if settings aren't available</returns>
|
|
public static AddressableAssetGroup GetOrCreateGroup(string name, bool includeInBuild = true)
|
|
{
|
|
// Use GetSettings(true) to ensure the settings asset is created if missing
|
|
var settings = GetAddressableSettings(true);
|
|
if (settings == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var group = settings.FindGroup(name);
|
|
if (group == null)
|
|
{
|
|
group = settings.CreateGroup(name, false, false, true, settings.DefaultGroup.Schemas);
|
|
|
|
// Configure the bundle schema if it exists
|
|
var bundleSchema = group.GetSchema<BundledAssetGroupSchema>();
|
|
if (bundleSchema != null)
|
|
{
|
|
bundleSchema.IncludeInBuild = includeInBuild;
|
|
}
|
|
}
|
|
|
|
return group;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create or move an asset entry to a specified Addressables group
|
|
/// </summary>
|
|
/// <param name="assetPath">Path to the asset</param>
|
|
/// <param name="groupName">Name of the group to add the asset to</param>
|
|
/// <param name="address">Optional custom address for the asset</param>
|
|
/// <returns>The created or moved asset entry, or null if failed</returns>
|
|
public static AddressableAssetEntry AddAssetToGroup(string assetPath, string groupName, string address = null)
|
|
{
|
|
if (string.IsNullOrEmpty(assetPath))
|
|
{
|
|
Debug.LogError("Cannot add asset to Addressables: Asset path is empty");
|
|
return null;
|
|
}
|
|
|
|
var settings = GetAddressableSettings(false);
|
|
if (settings == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var group = GetOrCreateGroup(groupName);
|
|
if (group == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var guid = AssetDatabase.AssetPathToGUID(assetPath);
|
|
if (string.IsNullOrEmpty(guid))
|
|
{
|
|
Debug.LogError($"Cannot add asset to Addressables: Invalid asset path {assetPath}");
|
|
return null;
|
|
}
|
|
|
|
var entry = settings.CreateOrMoveEntry(guid, group);
|
|
|
|
// Set custom address if provided
|
|
if (!string.IsNullOrEmpty(address))
|
|
{
|
|
entry.address = address;
|
|
}
|
|
|
|
settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entry, true);
|
|
return entry;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ensure an asset is in the specified addressable group
|
|
/// </summary>
|
|
/// <param name="assetPath">Path to the asset</param>
|
|
/// <param name="groupName">Target group name</param>
|
|
/// <param name="markDirty">Whether to mark settings as dirty</param>
|
|
/// <returns>True if the asset is now in the correct group</returns>
|
|
public static bool EnsureAssetInGroup(string assetPath, string groupName, bool markDirty = true)
|
|
{
|
|
var settings = GetAddressableSettings(false);
|
|
if (settings == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var guid = AssetDatabase.AssetPathToGUID(assetPath);
|
|
if (string.IsNullOrEmpty(guid))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var group = GetOrCreateGroup(groupName);
|
|
if (group == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var entry = settings.FindAssetEntry(guid);
|
|
|
|
// If entry exists but is in wrong group, move it
|
|
if (entry != null && entry.parentGroup != group)
|
|
{
|
|
settings.MoveEntry(entry, group);
|
|
if (markDirty)
|
|
{
|
|
settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryMoved, entry, true);
|
|
}
|
|
return true;
|
|
}
|
|
// If entry doesn't exist, create it
|
|
else if (entry == null)
|
|
{
|
|
entry = settings.CreateOrMoveEntry(guid, group);
|
|
if (markDirty)
|
|
{
|
|
settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryAdded, entry, true);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Entry already exists in correct group
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save any pending changes to addressable assets
|
|
/// </summary>
|
|
public static void SaveAddressableAssets()
|
|
{
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a label to an addressable asset
|
|
/// </summary>
|
|
/// <param name="assetPath">Path to the asset</param>
|
|
/// <param name="label">Label to add</param>
|
|
/// <returns>True if the label was successfully added</returns>
|
|
public static bool AddLabelToAsset(string assetPath, string label)
|
|
{
|
|
if (string.IsNullOrEmpty(assetPath) || string.IsNullOrEmpty(label))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var settings = GetAddressableSettings(false);
|
|
if (settings == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var guid = AssetDatabase.AssetPathToGUID(assetPath);
|
|
var entry = settings.FindAssetEntry(guid);
|
|
|
|
if (entry == null)
|
|
{
|
|
Debug.LogWarning($"Asset at {assetPath} is not addressable. Add it to a group first before applying labels.");
|
|
return false;
|
|
}
|
|
|
|
// Make sure the label exists in the settings
|
|
if (!settings.GetLabels().Contains(label))
|
|
{
|
|
settings.AddLabel(label);
|
|
}
|
|
|
|
// Add the label to the entry
|
|
entry.labels.Add(label);
|
|
settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryModified, entry, true);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ensure an asset is in an addressable group and has the specified label
|
|
/// </summary>
|
|
/// <param name="assetPath">Path to the asset</param>
|
|
/// <param name="groupName">Group to add the asset to</param>
|
|
/// <param name="label">Label to apply to the asset</param>
|
|
/// <returns>True if the asset was successfully added to the group and labeled</returns>
|
|
public static bool EnsureAssetInGroupWithLabel(string assetPath, string groupName, string label)
|
|
{
|
|
bool result = EnsureAssetInGroup(assetPath, groupName);
|
|
if (result && !string.IsNullOrEmpty(label))
|
|
{
|
|
result = AddLabelToAsset(assetPath, label);
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
}
|