/// <summary> /// Checks if this component would have a clash from the DisallowMultipleComponent attribute /// with existing components in a a list /// </summary> /// <param name="type">The type of component we want to test against</param> /// <param name="componentList">The list of existing components to compare against</param> /// <param name="excludeSelf">Used with hierarchical checks - ignores a component if is a match for the top level type, where a 'require component' won't actually need to add anything. </param> /// <<param name="conflictList">List to add to of found conflicting types (default is null)</param> /// <returns>True if the component has exclusive siblings, false otherwise</returns> static bool HasComponentClash(Type type, IComponentList <MonoBehaviour> componentList, bool excludeSelf = false, List <MonoBehaviour> conflictList = null) { k_Types.Clear(); type.IsDefinedGetInheritedTypes <DisallowMultipleComponent>(k_Types); var typeCounter = 0; while (typeCounter < k_Types.Count) { var ct = k_Types[typeCounter]; var componentInTypeChainMatchesParentTypeInList = componentList.components.Any(comp => { var compType = comp.GetType(); if (ct.IsAssignableFrom(compType)) { if ((conflictList != null) && (compType != type) && (!ct.IsAssignableFrom(typeof(MARSEntity)))) { conflictList.Add(comp); } return(true); } return(false); }); if (componentInTypeChainMatchesParentTypeInList) { return(!(excludeSelf && typeCounter == 0)); } typeCounter++; } return(false); }
/// <summary> /// Checks if this component would have a clash from one of its RequiredComponents being /// an exclusive sibling to another component already on the object /// </summary> /// <param name="type">The type of component to check for required components</param> /// <param name="componentList">The list of existing components to compare against</param> /// <returns>True if the component's required components have exclusive siblings, false otherwise</returns> static bool HasRequirementClash(Type type, IComponentList <MonoBehaviour> componentList) { k_Types.Clear(); type.IsDefinedGetInheritedTypes <RequireComponent>(k_Types); if (k_Types.Count == 0) { return(false); } var requiredComponent = type.GetAttribute <RequireComponent>(true); if (requiredComponent.m_Type0 != null) { if (HasComponentClash(requiredComponent.m_Type0, componentList, true) || HasRequirementClash(requiredComponent.m_Type0, componentList)) { return(true); } } if (requiredComponent.m_Type1 != null) { if (HasComponentClash(requiredComponent.m_Type1, componentList, true) || HasRequirementClash(requiredComponent.m_Type1, componentList)) { return(true); } } if (requiredComponent.m_Type2 != null) { if (HasComponentClash(requiredComponent.m_Type2, componentList, true) || HasRequirementClash(requiredComponent.m_Type2, componentList)) { return(true); } } return(false); }
/// <summary> /// Used to initialize the editor on <paramref name="serializedObject"/>, and set up editors for each component in <paramref name="components"/>. /// </summary> /// <param name="components"></param> /// <param name="serializedObject"></param> public void Init(IComponentList <TObject> components, SerializedObject serializedObject) { Assert.IsNotNull(components); Assert.IsNotNull(serializedObject); m_MarsInspectorSharedSettings = MarsInspectorSharedSettings.Instance; m_ComponentList = components; m_SerializedObject = serializedObject; m_ComponentProperty = serializedObject.FindProperty("m_Components"); Assert.IsNotNull(m_ComponentProperty); m_Editors = new List <ComponentInspector>(); // Create editors for existing settings for (var i = 0; i < m_ComponentList.components.Count; i++) { CreateEditor(m_ComponentList.components[i], m_ComponentProperty.GetArrayElementAtIndex(i)); } // Keep track of undo/redo to redraw the inspector when that happens Undo.undoRedoPerformed += OnUndoRedoPerformed; }