void SetEntryAssetType(TableEntryReference tableEntry, Type assetType, string entryCode) { long keyId = tableEntry.ReferenceType == TableEntryReference.Type.Name ? SharedData.GetId(tableEntry.Key, true) : tableEntry.KeyId; // Update type metadata AssetTypeMetadata entryMetadata = null; AssetTypeMetadata typeMetadata = null; // We cant use a foreach here as we are sometimes inside of a loop and exceptions will be thrown (Collection was modified). for (int i = 0; i < SharedData.Metadata.MetadataEntries.Count; ++i) { var md = SharedData.Metadata.MetadataEntries[i]; if (md is AssetTypeMetadata at) { if (at.Contains(keyId)) { if (!at.Type.IsAssignableFrom(assetType)) { at.RemoveEntry(keyId, entryCode); if (at.IsEmpty) { SharedData.Metadata.RemoveMetadata(at); } // Are other tables still using the type for the same id? if (at.Contains(tableEntry.KeyId)) { var name = SharedData.GetEntry(tableEntry.KeyId); Debug.LogWarning($"Table entry {name}({tableEntry.KeyId}) contains mixed types. Both {at.Type} and {assetType} are used."); } } else { entryMetadata = at; break; } } if (at.Type == assetType) { typeMetadata = at; break; } } } var foundMetadata = entryMetadata ?? typeMetadata; if (foundMetadata == null) { foundMetadata = new AssetTypeMetadata() { Type = assetType }; SharedData.Metadata.AddMetadata(foundMetadata); } foundMetadata.AddEntry(keyId, entryCode); }
/// <summary> /// Add a localized asset to the asset table. /// This function will ensure the localization system adds the asset to the Addressables system and sets the asset up for use. /// </summary> /// <param name="table">The table to add the asset to, must be part of the collection.</param> /// <param name="entryReference">The table entry Key or Key Id.</param> /// <param name="asset">The asset to add.</param> /// <param name="createUndo">Should an undo operation be created?</param> public virtual void AddAssetToTable(AssetTable table, TableEntryReference entryReference, Object asset, bool createUndo = false) { if (table == null) { throw new ArgumentNullException(nameof(table), "Can not add asset to null table"); } if (asset == null) { throw new ArgumentNullException(nameof(asset), "Can not add null asset to table"); } if (!ContainsTable(table)) { throw new Exception("The table does not belong to this collection."); } if (!EditorUtility.IsPersistent(table)) { throw new AssetNotPersistentException(table); } if (!EditorUtility.IsPersistent(asset)) { throw new AssetNotPersistentException(asset); } // Add the asset to the Addressables system and setup the table with the key to guid mapping. var aaSettings = LocalizationEditorSettings.Instance.GetAddressableAssetSettings(true); if (aaSettings == null) { return; } var undoGroup = Undo.GetCurrentGroup(); if (createUndo) { Undo.RecordObject(aaSettings, "Add asset to table"); } // Remove the old asset first var assetGuid = LocalizationEditorSettings.Instance.GetAssetGuid(asset); var tableEntry = table.GetEntryFromReference(entryReference); if (tableEntry != null) { if (tableEntry.Guid == assetGuid) { return; } RemoveAssetFromTable(table, entryReference, createUndo); } // Has the asset already been added? Perhaps it is being used by multiple tables or the user has added it manually. var entry = aaSettings.FindAssetEntry(assetGuid); var entryLabel = AddressHelper.FormatAssetLabel(table.LocaleIdentifier.Code); aaSettings.AddLabel(entryLabel); if (entry == null) { var group = LocalizationEditorSettings.Instance.GetGroup(aaSettings, FormatAssetTableCollectionName(table.LocaleIdentifier), true, createUndo); if (createUndo) { Undo.RecordObject(group, "Add asset to table"); } entry = aaSettings.CreateOrMoveEntry(assetGuid, group, true); entry.SetLabel(entryLabel, true); entry.address = LocalizationEditorSettings.Instance.FindUniqueAssetAddress(asset.name); } else { Undo.RecordObject(entry.parentGroup, "Add asset to table"); entry.SetLabel(entryLabel, true); UpdateAssetGroup(aaSettings, entry, createUndo); } // Update the table if (createUndo) { Undo.RecordObject(table, "Add asset to table"); Undo.RecordObject(table.SharedData, "Add asset to table"); } //else // Asset changes are not being saved correctly at the moment when using Undo. (LOC-82) { EditorUtility.SetDirty(table); EditorUtility.SetDirty(table.SharedData); } tableEntry = table.AddEntryFromReference(entryReference, assetGuid); // Update type metadata AssetTypeMetadata entryMetadata = null; AssetTypeMetadata typeMetadata = null; var assetType = asset.GetType(); // We cant use a foreach here as we are sometimes inside of a loop and exceptions will be thrown (Collection was modified). for (int i = 0; i < table.SharedData.Metadata.MetadataEntries.Count; ++i) { var md = table.SharedData.Metadata.MetadataEntries[i]; if (md is AssetTypeMetadata at) { if (at.Contains(tableEntry.KeyId)) { if (!at.Type.IsAssignableFrom(assetType)) { tableEntry.RemoveSharedMetadata(at); // Are other tables still using the type for the same id? if (at.Contains(tableEntry.KeyId)) { var name = SharedData.GetEntry(tableEntry.KeyId); Debug.LogWarning($"Table entry {name}({tableEntry.KeyId}) contains mixed types. Both {at.Type} and {assetType} are used."); } } else { entryMetadata = at; break; } } if (at.Type == assetType) { typeMetadata = at; break; } } } var foundMetadata = entryMetadata ?? typeMetadata; if (foundMetadata == null) { foundMetadata = new AssetTypeMetadata() { Type = assetType }; } tableEntry.AddSharedMetadata(foundMetadata); if (createUndo) { Undo.CollapseUndoOperations(undoGroup); } LocalizationEditorSettings.EditorEvents.RaiseAssetTableEntryAdded(this, table, tableEntry); }