using System; using System.Collections.Generic; using System.Reflection; using UnityEditor.AddressableAssets.GUI; using UnityEngine; using UnityEngine.ResourceManagement.Util; using UnityEngine.Serialization; namespace UnityEditor.AddressableAssets.Settings { /// /// Contains data for AddressableAssetGroups. /// public class AddressableAssetGroupSchema : ScriptableObject { [FormerlySerializedAs("m_group")] [AddressableReadOnly] [SerializeField] AddressableAssetGroup m_Group; /// /// Get the group that the schema belongs to. /// public AddressableAssetGroup Group { get { return m_Group; } internal set { m_Group = value; if (m_Group != null) { OnSetGroup(m_Group); Validate(); } } } /// /// Override this method to perform post creation initialization. /// /// The group that the schema is added to. protected virtual void OnSetGroup(AddressableAssetGroup group) { } internal virtual void Validate() { } /// /// Used to display the GUI of the schema. /// public virtual void OnGUI() { var type = GetType(); var so = new SerializedObject(this); var p = so.GetIterator(); p.Next(true); while (p.Next(false)) { var prop = type.GetField(p.name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); if (prop != null) EditorGUILayout.PropertyField(p, true); } so.ApplyModifiedProperties(); } /// /// Used to display the GUI of multiple selected groups. /// /// Schema instances in the other selected groups public virtual void OnGUIMultiple(List otherSchemas) { } /// /// Used to notify the addressables settings that data has been modified. This must be called by subclasses to ensure proper cache invalidation. /// /// Determines if this method call will post an event to the internal addressables event system protected void SetDirty(bool postEvent) { if (m_Group != null) { if (m_Group.Settings != null && m_Group.Settings.IsPersisted) { EditorUtility.SetDirty(this); AddressableAssetUtility.OpenAssetIfUsingVCIntegration(this); } if (m_Group != null) m_Group.SetDirty(AddressableAssetSettings.ModificationEvent.GroupSchemaModified, this, postEvent, false); } } /// /// Used for drawing properties in the inspector. /// public virtual void ShowAllProperties() { } /// /// Display mixed values for the specified property found in a list of schemas. /// /// The property. /// The list of schemas that may contain the property. /// The property type. /// The property name. protected void ShowMixedValue(SerializedProperty property, List otherSchemas, Type type, string propertyName) { foreach (var schema in otherSchemas) { var s_prop = (new SerializedObject(schema)).FindProperty(propertyName); if ((property.propertyType == SerializedPropertyType.Enum && (property.enumValueIndex != s_prop.enumValueIndex)) || (property.propertyType == SerializedPropertyType.String && (property.stringValue != s_prop.stringValue)) || (property.propertyType == SerializedPropertyType.Integer && (property.intValue != s_prop.intValue)) || (property.propertyType == SerializedPropertyType.Boolean && (property.boolValue != s_prop.boolValue))) { EditorGUI.showMixedValue = true; return; } if (type == typeof(ProfileValueReference)) { var field = property.serializedObject.targetObject.GetType().GetField(property.name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); string lhsId = (field?.GetValue(property.serializedObject.targetObject) as ProfileValueReference)?.Id; string rhsId = (field?.GetValue(s_prop.serializedObject.targetObject) as ProfileValueReference)?.Id; if (lhsId != null && rhsId != null && lhsId != rhsId) { EditorGUI.showMixedValue = true; return; } } if (type == typeof(SerializedType)) { var field = property.serializedObject.targetObject.GetType().GetField(property.name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); Type lhs = ((SerializedType)field?.GetValue(property.serializedObject.targetObject)).Value; Type rhs = ((SerializedType)field?.GetValue(s_prop.serializedObject.targetObject)).Value; if (lhs != null && rhs != null && lhs != rhs) { EditorGUI.showMixedValue = true; return; } } } } } }