/// <summary> /// Update the given InteractableEvent to the new type (which extends ReceiverBase) /// </summary> /// <param name="newType">new receiverbase subclass type to target</param> /// <param name="eventItem">InteractableEvent to target and update</param> private static void EventChanged(Type newType, SerializedProperty eventItem) { SerializedProperty className = eventItem.FindPropertyRelative("ClassName"); SerializedProperty assemblyQualifiedName = eventItem.FindPropertyRelative("AssemblyQualifiedName"); className.stringValue = newType.Name; assemblyQualifiedName.stringValue = newType.AssemblyQualifiedName; SerializedProperty settings = eventItem.FindPropertyRelative("Settings"); ReceiverBase defaultReceiver = (ReceiverBase)Activator.CreateInstance(newType, new UnityEvent()); InspectorFieldsUtility.ClearSettingsList(settings, InspectorFieldsUtility.GetInspectorFields(defaultReceiver)); }
/// <summary> /// Create the event and setup the values from the inspector /// </summary> public static ReceiverBase GetReceiver(InteractableEvent iEvent, InteractableTypesContainer interactableTypes) { #if UNITY_EDITOR int index = InspectorField.ReverseLookup(iEvent.ClassName, interactableTypes.ClassNames); Type eventType = interactableTypes.Types[index]; #else Type eventType = Type.GetType(iEvent.AssemblyQualifiedName); #endif // apply the settings? ReceiverBase newEvent = (ReceiverBase)Activator.CreateInstance(eventType, iEvent.Event); InspectorGenericFields <ReceiverBase> .LoadSettings(newEvent, iEvent.Settings); return(newEvent); }
/// <summary> /// Create the event and setup the values from the inspector /// </summary> public static ReceiverBase CreateReceiver(InteractableEvent iEvent) { // Temporary workaround // This is to fix a bug in GA where the AssemblyQualifiedName was never actually saved. Functionality would work in editor...but never on device player if (iEvent.ReceiverType == null) { var correctType = TypeCacheUtility.GetSubClasses <ReceiverBase>().Where(s => s?.Name == iEvent.ClassName).First(); iEvent.ReceiverType = correctType; } ReceiverBase newEvent = (ReceiverBase)Activator.CreateInstance(iEvent.ReceiverType, iEvent.Event); InspectorGenericFields <ReceiverBase> .LoadSettings(newEvent, iEvent.Settings); return(newEvent); }
/// <summary> /// Add new events/receivers to the list and grab all the InspectorFields so we can render them in the inspector /// </summary> public ReceiverData AddReceiver(Type type) { ReceiverBase receiver = (ReceiverBase)Activator.CreateInstance(type, Event); // get the settings for the inspector List <InspectorFieldData> fields = new List <InspectorFieldData>(); Type myType = receiver.GetType(); int index = 0; ReceiverData data = new ReceiverData(); foreach (PropertyInfo prop in myType.GetProperties()) { var attrs = (InspectorField[])prop.GetCustomAttributes(typeof(InspectorField), false); foreach (var attr in attrs) { fields.Add(new InspectorFieldData() { Name = prop.Name, Attributes = attr, Value = prop.GetValue(receiver, null) }); } index++; } index = 0; foreach (FieldInfo field in myType.GetFields()) { var attrs = (InspectorField[])field.GetCustomAttributes(typeof(InspectorField), false); foreach (var attr in attrs) { fields.Add(new InspectorFieldData() { Name = field.Name, Attributes = attr, Value = field.GetValue(receiver) }); } index++; } data.Fields = fields; data.Name = receiver.Name; data.HideUnityEvents = receiver.HideUnityEvents; return(data); }
/// <summary> /// Render event properties for the given event item. If item has been removed, returns true. False otherwise /// </summary> /// <param name="eventItem">serialized property of the event item to render properties from</param> /// <returns>If item has been removed, returns true. False otherwise</returns> public static bool RenderEvent(SerializedProperty eventItem, bool canRemove = true) { using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { SerializedProperty uEvent = eventItem.FindPropertyRelative("Event"); SerializedProperty eventName = eventItem.FindPropertyRelative("Name"); SerializedProperty className = eventItem.FindPropertyRelative("ClassName"); SerializedProperty assemblyQualifiedName = eventItem.FindPropertyRelative("AssemblyQualifiedName"); Type receiverType; InspectorUIUtility.DrawHeader("Event Receiver Type"); using (new EditorGUILayout.HorizontalScope()) { Rect position = EditorGUILayout.GetControlRect(); using (new EditorGUI.PropertyScope(position, SelectEventLabel, className)) { var receiverTypes = TypeCacheUtility.GetSubClasses <ReceiverBase>(); var recevierClassNames = receiverTypes.Select(t => t?.Name).ToArray(); int id = Array.IndexOf(recevierClassNames, className.stringValue); int newId = EditorGUI.Popup(position, id, recevierClassNames); if (newId == -1) { newId = 0; } receiverType = receiverTypes[newId]; // Temporary workaround to fix bug shipped in GA where assemblyQualifiedName was never set if (string.IsNullOrEmpty(assemblyQualifiedName.stringValue)) { assemblyQualifiedName.stringValue = receiverType.AssemblyQualifiedName; } if (id != newId) { EventChanged(receiverType, eventItem); } } if (canRemove) { if (InspectorUIUtility.FlexButton(new GUIContent("Remove Event"))) { return(true); } } } EditorGUILayout.Space(); InspectorUIUtility.DrawHeader("Event Properties"); ReceiverBase receiver = (ReceiverBase)Activator.CreateInstance(receiverType, new UnityEvent()); if (!receiver.HideUnityEvents) { EditorGUILayout.PropertyField(uEvent, new GUIContent(receiver.Name)); } SerializedProperty eventSettings = eventItem.FindPropertyRelative("Settings"); // If fields for given receiver class type have been changed, update the related inspector field data var fieldList = InspectorFieldsUtility.GetInspectorFields(receiver); if (!InspectorFieldsUtility.AreFieldsSame(eventSettings, fieldList)) { InspectorFieldsUtility.UpdateSettingsList(eventSettings, fieldList); } for (int index = 0; index < eventSettings.arraySize; index++) { SerializedProperty propertyField = eventSettings.GetArrayElementAtIndex(index); bool isEvent = InspectorFieldsUtility.IsPropertyType(propertyField, InspectorField.FieldTypes.Event); if (!receiver.HideUnityEvents || !isEvent) { InspectorFieldsUtility.DisplayPropertyField(eventSettings.GetArrayElementAtIndex(index)); } } } return(false); }