using System; using System.Collections.Generic; using UnityEditor.Presets; using UnityEngine; using UnityEngine.Assertions; namespace UnityEditor.AddressableAssets.Settings { /// /// Used to create template groups to make it easier for the user to create new groups. /// [CreateAssetMenu(fileName = "AddressableAssetGroupTemplate.asset", menuName = "Addressables/Group Templates/Blank Group Template")] public class AddressableAssetGroupTemplate : ScriptableObject, IGroupTemplate { [SerializeField] private List m_SchemaObjects = new List(); [SerializeField] private string m_Description; [SerializeField] private AddressableAssetSettings m_Settings; internal AddressableAssetSettings Settings { get { if (m_Settings == null) m_Settings = AddressableAssetSettingsDefaultObject.Settings; return m_Settings; } set { m_Settings = value; } } /// /// Returns a list of Preset objects for AddressableAssetGroupSchema associated with this template /// internal List SchemaPresetObjects { get { List m_SchemaPresetObjects = new List(m_SchemaObjects.Count); foreach (AddressableAssetGroupSchema schemaObject in m_SchemaObjects) m_SchemaPresetObjects.Add(new Preset(schemaObject)); return m_SchemaPresetObjects; } } /// /// Returns the list of Preset objects of AddressableAssetGroupSchema associated with this template /// public List SchemaObjects { get { return m_SchemaObjects; } } /// /// The name of the AddressableAssetGroupTemplate /// public string Name { get { return name; } } /// /// The description of the AddressableAssetGroupTemplate /// public string Description { get { return m_Description; } set { m_Description = value; } } /// /// Gets the types of the AddressableAssetGroupSchema associated with this template /// /// AddressableAssetGroupSchema types for schema on this template public Type[] GetTypes() { var types = new Type[m_SchemaObjects.Count]; for (int i = 0; i < types.Length; i++) types[i] = m_SchemaObjects[i].GetType(); return types; } /// /// Applies schema values for the group to the schema values found in the template /// /// The AddressableAssetGroup to apply the schema settings to public void ApplyToAddressableAssetGroup(AddressableAssetGroup group) { foreach (AddressableAssetGroupSchema schema in group.Schemas) { List presets = SchemaPresetObjects; foreach (Preset p in presets) { Assert.IsNotNull(p); if (p.CanBeAppliedTo(schema)) { p.ApplyTo(schema); schema.Group = group; } } } } /// /// Adds the AddressableAssetGroupSchema of type to the template. /// /// The Type for the AddressableAssetGroupSchema to add to this template. /// If true, the event is propagated to callbacks. /// If true, the type was added successfully. public bool AddSchema(Type type, bool postEvent = true) { if (type == null) { Debug.LogWarning("Cannot remove schema with null type."); return false; } if (!typeof(AddressableAssetGroupSchema).IsAssignableFrom(type)) { Debug.LogWarningFormat("Invalid Schema type {0}. Schemas must inherit from AddressableAssetGroupSchema.", type.FullName); return false; } foreach (AddressableAssetGroupSchema schemaObject in m_SchemaObjects) { if (schemaObject.GetType() == type) { Debug.LogError("Scheme of type " + type + " already exists"); return false; } } AddressableAssetGroupSchema schemaInstance = (AddressableAssetGroupSchema)CreateInstance(type); if (schemaInstance != null) { schemaInstance.name = type.Name; try { schemaInstance.hideFlags |= HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(schemaInstance, this); } catch (Exception e) { Console.WriteLine(e); throw; } m_SchemaObjects.Add(schemaInstance); SetDirty(AddressableAssetSettings.ModificationEvent.GroupTemplateSchemaAdded, this, postEvent); AssetDatabase.SaveAssets(); } return schemaInstance != null; } /// /// Removes the AddressableAssetGroupSchema of the type from the template. /// /// The type of AddressableAssetGroupSchema to be removed. /// If true, the event is propagated to callbacks. /// If true, the type was removed successfully. public bool RemoveSchema(Type type, bool postEvent = true) { if (type == null) { Debug.LogWarning("Cannot remove schema with null type."); return false; } if (!typeof(AddressableAssetGroupSchema).IsAssignableFrom(type)) { Debug.LogWarningFormat("Invalid Schema type {0}. Schemas must inherit from AddressableAssetGroupSchema.", type.FullName); return false; } for (int i = 0; i < m_SchemaObjects.Count; ++i) { if (m_SchemaObjects[i].GetType() == type) return RemoveSchema(i, postEvent); } return false; } /// /// Removes the Schema at the given index. /// /// The index of the object to be removed. /// If true, the event is propagated to callbacks. /// If true, the type was removed successfully. internal bool RemoveSchema(int index, bool postEvent = true) { if (index == -1) return false; AssetDatabase.RemoveObjectFromAsset(m_SchemaObjects[index]); DestroyImmediate(m_SchemaObjects[index]); m_SchemaObjects.RemoveAt(index); SetDirty(AddressableAssetSettings.ModificationEvent.GroupTemplateSchemaRemoved, this, postEvent); AssetDatabase.SaveAssets(); return true; } /// /// Marks the object as modified. /// /// The event type that is changed. /// The object data that corresponds to the event. /// If true, the event is propagated to callbacks. public void SetDirty(AddressableAssetSettings.ModificationEvent modificationEvent, object eventData, bool postEvent) { if (Settings != null) { if (Settings.IsPersisted && this != null) { EditorUtility.SetDirty(this); AddressableAssetUtility.OpenAssetIfUsingVCIntegration(this); } Settings.SetDirty(modificationEvent, eventData, postEvent, false); } } /// /// Checks if the group contains a schema of a given type. /// /// The schema type. /// True if the schema type or subclass has been added to this group. public bool HasSchema(Type type) { return GetSchemaByType(type) != null; } /// /// Gets an added schema of the specified type. /// /// The schema type. /// The schema if found, otherwise null. public AddressableAssetGroupSchema GetSchemaByType(Type type) { foreach (var schema in m_SchemaObjects) { if (schema.GetType() == type) { return schema; } } return null; } /// /// Gets the index of a schema based on its specified type. /// /// The schema type. /// Valid index if found, otherwise returns -1. public int FindSchema(Type type) { for (int i = 0; i < m_SchemaObjects.Count; i++) { if (m_SchemaObjects[i].GetType() == type) { return i; } } return -1; } } }