public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); DropdownAttribute dropdownAttribute = PropertyUtility.GetAttribute <DropdownAttribute>(property); UnityEngine.Object target = PropertyUtility.GetTargetObject(property); FieldInfo fieldInfo = ReflectionUtility.GetField(target, property.name); FieldInfo valuesFieldInfo = ReflectionUtility.GetField(target, dropdownAttribute.ValuesFieldName); if (valuesFieldInfo == null) { EditorDrawUtility.DrawHelpBox(string.Format("{0} 不能找到叫做 \"{1}\" 的值", dropdownAttribute.GetType().Name, dropdownAttribute.ValuesFieldName), MessageType.Warning, context: target, logToConsole: false); EditorDrawUtility.DrawPropertyField(property); } else if (valuesFieldInfo.GetValue(target) is IList && fieldInfo.FieldType == this.GetElementType(valuesFieldInfo)) { // 所选的值 object selectedValue = fieldInfo.GetValue(target); // 所有值和可选项 IList valuesList = (IList)valuesFieldInfo.GetValue(target); object[] values = new object[valuesList.Count]; string[] displayOptions = new string[valuesList.Count]; for (int i = 0; i < values.Length; i++) { object value = valuesList[i]; values[i] = value; displayOptions[i] = value.ToString(); } // 可选择值得索引 int selectedValueIndex = Array.IndexOf(values, selectedValue); if (selectedValueIndex < 0) { selectedValueIndex = 0; } // 绘制下拉栏 this.DrawDropdown(target, fieldInfo, property.displayName, selectedValueIndex, values, displayOptions); } else if (valuesFieldInfo.GetValue(target) is IDropdownList) { // 当前值 object selectedValue = fieldInfo.GetValue(target); // 当前值得索引,和所有值,显示出的选项 IDropdownList dropdown = (IDropdownList)valuesFieldInfo.GetValue(target); IEnumerator <KeyValuePair <string, object> > dropdownEnumerator = dropdown.GetEnumerator(); int index = -1; int selectedValueIndex = -1; List <object> values = new List <object>(); List <string> displayOptions = new List <string>(); while (dropdownEnumerator.MoveNext()) { index++; KeyValuePair <string, object> current = dropdownEnumerator.Current; if (current.Value.Equals(selectedValue)) { selectedValueIndex = index; } values.Add(current.Value); displayOptions.Add(current.Key); } if (selectedValueIndex < 0) { selectedValueIndex = 0; } // 绘制下拉栏 this.DrawDropdown(target, fieldInfo, property.displayName, selectedValueIndex, values.ToArray(), displayOptions.ToArray()); } else { EditorDrawUtility.DrawHelpBox(typeof(DropdownAttribute).Name + " 只作用于指定字段与指定数组的元素类型相等时!!八嘎", MessageType.Warning, context: target, logToConsole: false); EditorDrawUtility.DrawPropertyField(property); } }
protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(rect, label, property); DropdownAttribute dropdownAttribute = (DropdownAttribute)attribute; object target = PropertyUtility.GetTargetObjectWithProperty(property); object valuesObject = GetValues(property, dropdownAttribute.ValuesName); FieldInfo dropdownField = ReflectionUtility.GetField(target, property.name); if (AreValuesValid(valuesObject, dropdownField)) { if (valuesObject is IList && dropdownField.FieldType == GetElementType(valuesObject)) { // Selected value object selectedValue = dropdownField.GetValue(target); // Values and display options IList valuesList = (IList)valuesObject; object[] values = new object[valuesList.Count]; string[] displayOptions = new string[valuesList.Count]; for (int i = 0; i < values.Length; i++) { object value = valuesList[i]; values[i] = value; displayOptions[i] = value == null ? "<null>" : value.ToString(); } // Selected value index int selectedValueIndex = Array.IndexOf(values, selectedValue); if (selectedValueIndex < 0) { selectedValueIndex = 0; } NaughtyEditorGUI.Dropdown( rect, property.serializedObject, target, dropdownField, label.text, selectedValueIndex, values, displayOptions); } else if (valuesObject is IDropdownList) { // Current value object selectedValue = dropdownField.GetValue(target); // Current value index, values and display options int index = -1; int selectedValueIndex = -1; List <object> values = new List <object>(); List <string> displayOptions = new List <string>(); IDropdownList dropdown = (IDropdownList)valuesObject; using (IEnumerator <KeyValuePair <string, object> > dropdownEnumerator = dropdown.GetEnumerator()) { while (dropdownEnumerator.MoveNext()) { index++; KeyValuePair <string, object> current = dropdownEnumerator.Current; if (current.Value?.Equals(selectedValue) == true) { selectedValueIndex = index; } values.Add(current.Value); if (current.Key == null) { displayOptions.Add("<null>"); } else if (string.IsNullOrWhiteSpace(current.Key)) { displayOptions.Add("<empty>"); } else { displayOptions.Add(current.Key); } } } if (selectedValueIndex < 0) { selectedValueIndex = 0; } NaughtyEditorGUI.Dropdown( rect, property.serializedObject, target, dropdownField, label.text, selectedValueIndex, values.ToArray(), displayOptions.ToArray()); } } else { string message = string.Format("Invalid values with name '{0}' provided to '{1}'. Either the values name is incorrect or the types of the target field and the values field/property/method don't match", dropdownAttribute.ValuesName, dropdownAttribute.GetType().Name); DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning); } EditorGUI.EndProperty(); }
public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); DropdownAttribute dropdownAttribute = PropertyUtility.GetAttribute <DropdownAttribute>(property); UnityEngine.Object target = PropertyUtility.GetTargetObject(property); FieldInfo fieldInfo = target.GetType().GetField(property.name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); FieldInfo valuesFieldInfo = target.GetType().GetField(dropdownAttribute.ValuesFieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); if (valuesFieldInfo == null) { this.DrawWarningBox(string.Format("{0} cannot find a values field with name \"{1}\"", dropdownAttribute.GetType().Name, dropdownAttribute.ValuesFieldName)); EditorGUILayout.PropertyField(property, true); } else if (fieldInfo.FieldType == valuesFieldInfo.FieldType.GetElementType()) { // Selected value object selectedValue = fieldInfo.GetValue(target); // Values and display options IList valuesList = (IList)valuesFieldInfo.GetValue(target); object[] values = new object[valuesList.Count]; string[] displayOptions = new string[valuesList.Count]; for (int i = 0; i < values.Length; i++) { object value = valuesList[i]; values[i] = value; displayOptions[i] = value.ToString(); } // Selected value index int selectedValueIndex = Array.IndexOf(values, selectedValue); if (selectedValueIndex < 0) { selectedValueIndex = 0; } // Draw the dropdown this.DrawDropdown(target, fieldInfo, property.displayName, selectedValueIndex, values, displayOptions); } else if (valuesFieldInfo.GetValue(target) is IDropdownList) { // Current value object selectedValue = fieldInfo.GetValue(target); // Current value index, values and display options IDropdownList dropdown = (IDropdownList)valuesFieldInfo.GetValue(target); IEnumerator <KeyValuePair <string, object> > dropdownEnumerator = dropdown.GetEnumerator(); int index = -1; int selectedValueIndex = -1; List <object> values = new List <object>(); List <string> displayOptions = new List <string>(); while (dropdownEnumerator.MoveNext()) { index++; KeyValuePair <string, object> current = dropdownEnumerator.Current; if (current.Value.Equals(selectedValue)) { selectedValueIndex = index; } values.Add(current.Value); displayOptions.Add(current.Key); } if (selectedValueIndex < 0) { selectedValueIndex = 0; } // Draw the dropdown this.DrawDropdown(target, fieldInfo, property.displayName, selectedValueIndex, values.ToArray(), displayOptions.ToArray()); } else { this.DrawWarningBox(typeof(DropdownAttribute).Name + " works only when the type of the field is equal to the element type of the array"); EditorGUILayout.PropertyField(property, true); } }
/// <summary> /// Draws the property. /// </summary> /// <param name="property">Property.</param> public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); DropdownAttribute dropdownAttribute = PropertyUtility.GetAttribute <DropdownAttribute>(property); UnityEngine.Object target = PropertyUtility.GetTargetObject(property); FieldInfo fieldInfo = ReflectionUtility.GetField(target, property.name); FieldInfo valuesFieldInfo = ReflectionUtility.GetField(target, dropdownAttribute.ValuesFieldName); /// null if (valuesFieldInfo == null) { this.DrawWarningBox(string.Format("{0} cannot find a values field with name \"{1}\"", dropdownAttribute.GetType().Name, dropdownAttribute.ValuesFieldName)); EditorGUILayout.PropertyField(property, true); } /// type is GetElementType ( int, float... ) else if (fieldInfo.FieldType == valuesFieldInfo.FieldType.GetElementType()) { // Selected value object selectedValue = fieldInfo.GetValue(target); // Values and display options IList valuesList = (IList)valuesFieldInfo.GetValue(target); object[] values = new object[valuesList.Count]; string[] displayOptions = new string[valuesList.Count]; for (int i = 0; i < values.Length; i++) { object value = valuesList[i]; values[i] = value; displayOptions[i] = value.ToString(); } // Selected value index int selectedValueIndex = Array.IndexOf(values, selectedValue); if (selectedValueIndex < 0) { selectedValueIndex = 0; } // Draw the dropdown this.DrawDropdown(target, fieldInfo, property.displayName, selectedValueIndex, values, displayOptions); } // type is ScriptableObject else if (valuesFieldInfo.GetValue(target) is ScriptableObject) { // Current value index, values and display options ActionBehaviour.StringSet stringSet = (ActionBehaviour.StringSet)valuesFieldInfo.GetValue(target); if (null != stringSet) { // Current value object selectedValue = fieldInfo.GetValue(target); Debug.Log(stringSet.ToString()); List <string> valuesList = stringSet.GetList(); object[] values = new object[valuesList.Count]; string[] displayOptions = new string[valuesList.Count]; for (int i = 0; i < values.Length; i++) { object value = valuesList[i]; values[i] = value; displayOptions[i] = value.ToString(); } // Selected value index int selectedValueIndex = Array.IndexOf(values, selectedValue); if (selectedValueIndex < 0) { Array.Resize <object>(ref values, values.Length + 1); Array.Resize <string>(ref displayOptions, displayOptions.Length + 1); selectedValueIndex = values.Length - 1; values[selectedValueIndex] = selectedValue; displayOptions[selectedValueIndex] = "[new]" + selectedValue.ToString(); } // Draw the dropdown this.DrawDropdown(target, fieldInfo, property.displayName, selectedValueIndex, values, displayOptions); } else { this.DrawWarningBox(typeof(DropdownAttribute).Name + " Wrong Droplist set"); EditorGUILayout.PropertyField(property, true); } } // type is IDropdownList else if (valuesFieldInfo.GetValue(target) is IDropdownList) { // Current value object selectedValue = fieldInfo.GetValue(target); // Current value index, values and display options IDropdownList dropdown = (IDropdownList)valuesFieldInfo.GetValue(target); IEnumerator <KeyValuePair <string, object> > dropdownEnumerator = dropdown.GetEnumerator(); int index = -1; int selectedValueIndex = -1; List <object> values = new List <object>(); List <string> displayOptions = new List <string>(); while (dropdownEnumerator.MoveNext()) { index++; KeyValuePair <string, object> current = dropdownEnumerator.Current; if (current.Value.Equals(selectedValue)) { selectedValueIndex = index; } values.Add(current.Value); displayOptions.Add(current.Key); } if (selectedValueIndex < 0) { selectedValueIndex = 0; } // Draw the dropdown this.DrawDropdown(target, fieldInfo, property.displayName, selectedValueIndex, values.ToArray(), displayOptions.ToArray()); } // otherwise else { this.DrawWarningBox(typeof(DropdownAttribute).Name + " works only when the type of the field is equal to the element type of the array"); EditorGUILayout.PropertyField(property, true); } }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(position, label, property); var dropdownAttribute = attribute as DropdownAttribute; object target = property.GetTargetObjectWithProperty(); object valuesObject = GetValues(property, dropdownAttribute.ValuesCollectionName); FieldInfo dropdownField = target.GetField(property.name); if (AreValuesValid(valuesObject, dropdownField)) { if (valuesObject is IList && dropdownField.FieldType == GetElementType(valuesObject)) { // Selected value object selectedValue = dropdownField.GetValue(target); // Values and display options IList valuesList = (IList)valuesObject; object[] values = new object[valuesList.Count]; string[] displayOptions = new string[valuesList.Count]; for (int i = 0; i < values.Length; i++) { object value = valuesList[i]; values[i] = value; displayOptions[i] = value == null ? "<null>" : value.ToString(); } // Selected value index int selectedValueIndex = Array.IndexOf(values, selectedValue); if (selectedValueIndex < 0) { selectedValueIndex = 0; } DrawDropdown( position, property.serializedObject, target, dropdownField, label.text, selectedValueIndex, values, displayOptions); } else if (valuesObject is IDropdownList) { // Current value object selectedValue = dropdownField.GetValue(target); // Current value index, values and display options int index = -1; int selectedValueIndex = -1; List <object> values = new List <object>(); List <string> displayOptions = new List <string>(); IDropdownList dropdown = (IDropdownList)valuesObject; using (IEnumerator <KeyValuePair <string, object> > dropdownEnumerator = dropdown.GetEnumerator()) { while (dropdownEnumerator.MoveNext()) { index++; KeyValuePair <string, object> current = dropdownEnumerator.Current; if (current.Value?.Equals(selectedValue) == true) { selectedValueIndex = index; } values.Add(current.Value); if (current.Key == null) { displayOptions.Add("<null>"); } else if (string.IsNullOrWhiteSpace(current.Key)) { displayOptions.Add("<empty>"); } else { displayOptions.Add(current.Key); } } } if (selectedValueIndex < 0) { selectedValueIndex = 0; } DrawDropdown( position, property.serializedObject, target, dropdownField, label.text, selectedValueIndex, values.ToArray(), displayOptions.ToArray()); } } else { var message = $"ERROR! Invalid values {dropdownAttribute.ValuesCollectionName} {dropdownAttribute.GetType().Name}"; DrawErrorMessage(position, message); } EditorGUI.EndProperty(); }
private void DrawProperty(ValueWrapper wrapper, DropdownAttribute attribute) { var target = wrapper.Target; //FieldInfo fieldInfo = ReflectionUtility.GetField(target, attribute.name); FieldInfo valuesFieldInfo = ReflectionUtility.GetField(target, attribute.ValuesFieldName); if (valuesFieldInfo == null) { FieldNull(wrapper, attribute); return; } if (valuesFieldInfo.GetValue(target) is IList && wrapper.Type == GetElementType(valuesFieldInfo)) { // Selected value object selectedValue = wrapper.GetValue(); // Values and display options IList valuesList = (IList)valuesFieldInfo.GetValue(target); var values = new object[valuesList.Count]; var displayOptions = new string[valuesList.Count]; for (int i = 0; i < values.Length; i++) { object value = valuesList[i]; values[i] = value; displayOptions[i] = value.ToString(); } // Selected value index var selectedValueIndex = Array.IndexOf(values, selectedValue); if (selectedValueIndex < 0) { selectedValueIndex = 0; } this.DrawDropdown(wrapper, selectedValueIndex, values, displayOptions); } if (valuesFieldInfo.GetValue(target) is IDropdownList) { // Current value object selectedValue = wrapper.GetValue(); // Current value index, values and display options IDropdownList dropdown = (IDropdownList)valuesFieldInfo.GetValue(target); IEnumerator <KeyValuePair <string, object> > dropdownEnumerator = dropdown.GetEnumerator(); int index = -1; var selectedValueIndex = -1; List <object> values = new List <object>(); List <string> displayOptions = new List <string>(); while (dropdownEnumerator.MoveNext()) { index++; KeyValuePair <string, object> current = dropdownEnumerator.Current; if (current.Value.Equals(selectedValue)) { selectedValueIndex = index; } values.Add(current.Value); displayOptions.Add(current.Key); } dropdownEnumerator.Dispose(); if (selectedValueIndex < 0) { selectedValueIndex = 0; } this.DrawDropdown(wrapper, selectedValueIndex, values.ToArray(), displayOptions.ToArray()); } NotArray(wrapper); }
protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(rect, label, property); DropdownIndexAttribute dropdownAttribute = (DropdownIndexAttribute)attribute; object valuesObject = GetValues(property, dropdownAttribute.ValuesName); if (property.propertyType == SerializedPropertyType.Integer) { if (valuesObject is IList) { // Selected value index int selectedValueIndex = property.intValue; // Values and display options IList valuesList = (IList)valuesObject; string[] displayOptions = new string[valuesList.Count]; for (int i = 0; i < valuesList.Count; i++) { object value = valuesList[i]; displayOptions[i] = value == null ? "<null>" : value.ToString(); } property.intValue = EditorGUI.Popup(rect, label.text, selectedValueIndex, displayOptions); } else if (valuesObject is IDropdownList) { // Selected value index int selectedValueIndex = property.intValue; // display options List <string> displayOptions = new List <string>(); IDropdownList dropdown = (IDropdownList)valuesObject; using (IEnumerator <KeyValuePair <string, object> > dropdownEnumerator = dropdown.GetEnumerator()) { while (dropdownEnumerator.MoveNext()) { KeyValuePair <string, object> current = dropdownEnumerator.Current; if (current.Key == null) { displayOptions.Add("<null>"); } else if (string.IsNullOrWhiteSpace(current.Key)) { displayOptions.Add("<empty>"); } else { displayOptions.Add(current.Key); } } } if (selectedValueIndex < 0) { selectedValueIndex = 0; } property.intValue = EditorGUI.Popup(rect, label.text, selectedValueIndex, displayOptions.ToArray()); } } else { string message = $"{nameof(DropdownIndexAttribute)} supports only int fields"; DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning); } EditorGUI.EndProperty(); }