Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections.Generic;
- using UnityEditor;
- using UnityEditor.UIElements;
- using UnityEngine;
- using UnityEngine.UIElements;
- [CustomPropertyDrawer(typeof(ExposeAttribute))]
- public class ExposeAttributePropertyDrawer : PropertyDrawer
- {
- // UXML
- private VisualTreeAsset _exposedFieldUxml;
- private VisualTreeAsset ExposedFieldUxml
- {
- get
- {
- if (_exposedFieldUxml == null)
- {
- var assetPath = AssetDatabase.GUIDToAssetPath(k_exposedFieldUxmlGuid);
- _exposedFieldUxml = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(assetPath);
- }
- return _exposedFieldUxml;
- }
- }
- // VisualElements
- private VisualElement _root;
- private TemplateContainer _mainPanel;
- private PropertyField _propertyField;
- private VisualElement _propertyFieldsPanel;
- private Foldout _foldout;
- // Constant values
- private const string k_exposedFieldUxmlGuid = "1da7b35196ba6a24a940668dc4b2d818";
- public override VisualElement CreatePropertyGUI(SerializedProperty property)
- {
- CreateRoot();
- InstantiateUXML();
- QueryElements();
- SetupElements(property);
- AddVisualElementsToRoot();
- return _root;
- }
- private void CreateRoot()
- {
- _root = new VisualElement();
- }
- private void InstantiateUXML()
- {
- _mainPanel = ExposedFieldUxml.Instantiate();
- }
- private void QueryElements()
- {
- QueryPropertyField();
- QueryPropertyFieldsPanel();
- QueryFoldout();
- }
- private void SetupElements(SerializedProperty property)
- {
- SetupPropertyField(property);
- // SetupFoldout(property);
- }
- private void AddVisualElementsToRoot()
- {
- _root.Add(_mainPanel);
- }
- private void QueryPropertyField()
- {
- _propertyField = _mainPanel.Q<PropertyField>("PropertyField");
- if (_propertyField == null)
- {
- Debug.LogError("_mainPanel.Q<PropertyField>(\"PropertyField\") returned null!");
- return;
- }
- }
- private void QueryPropertyFieldsPanel()
- {
- _propertyFieldsPanel = _mainPanel.Q<VisualElement>("PropertyFieldsPanel");
- if (_propertyFieldsPanel == null)
- {
- Debug.LogError("_mainPanel.Q<VisualElement>(\"PropertyFieldsPanel\") returned null!");
- return;
- }
- }
- private void QueryFoldout()
- {
- _foldout = _propertyFieldsPanel.Q<Foldout>();
- if (_foldout == null)
- {
- Debug.LogError("foldoutRoot.Q<Foldout>() returned null!");
- return;
- }
- }
- private void SetupPropertyField(SerializedProperty property)
- {
- _propertyField.BindProperty(property);
- _propertyField.RegisterValueChangeCallback(OnMainPropertyFieldChange);
- void OnMainPropertyFieldChange(SerializedPropertyChangeEvent changeEvent)
- {
- if (changeEvent.changedProperty.objectReferenceValue == null)
- {
- _propertyFieldsPanel.style.display = DisplayStyle.None;
- return;
- }
- _propertyFieldsPanel.style.display = DisplayStyle.Flex;
- SetupFoldout(property);
- }
- }
- /// <summary>
- /// Set text, create SerializedObject, create and add PropertyFields and register callback.
- /// </summary>
- /// <param name="property"></param>
- /// <param name="propertyFields"></param>
- private void SetupFoldout(SerializedProperty property)
- {
- if (property.objectReferenceValue == null)
- {
- _foldout.style.display = DisplayStyle.None;
- return;
- }
- _foldout.style.display = DisplayStyle.Flex;
- _foldout.text = $"Edit \"{property.objectReferenceValue.name}\"";
- var serializedObject = CreateSerializedObject();
- var propertyFields = CreateFoldoutPropertyFields();
- _foldout.Clear();
- foreach (var propField in propertyFields)
- _foldout.Add(propField);
- _foldout.viewDataKey = GetFoldoutDataKey(property);
- _foldout.RegisterValueChangedCallback(OnFoldoutValueChange);
- SerializedObject CreateSerializedObject()
- {
- return new SerializedObject(property.objectReferenceValue);
- }
- PropertyField[] CreateFoldoutPropertyFields()
- {
- var prop = serializedObject.GetIterator();
- if (!prop.Next(true))
- return new PropertyField[0];
- int currentPropIndex = 0;
- List<PropertyField> propertyFieldsList = new(16);
- do
- {
- if (currentPropIndex > 9)
- {
- var propCopy = prop.Copy();
- var propPropField = new PropertyField(propCopy);
- propPropField.BindProperty(serializedObject);
- propertyFieldsList.Add(propPropField);
- }
- currentPropIndex++;
- }
- while (prop.Next(false));
- return propertyFieldsList.ToArray();
- }
- void OnFoldoutValueChange(ChangeEvent<bool> changeEvent)
- {
- if (changeEvent.newValue)
- foreach (var propField in propertyFields)
- propField.style.display = DisplayStyle.Flex;
- else
- foreach (var propField in propertyFields)
- propField.style.display = DisplayStyle.None;
- }
- }
- private string GetFoldoutDataKey(SerializedProperty property)
- {
- return $"{property.serializedObject.targetObject.GetInstanceID()}.{property.name}";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement