I’m making a custom property drawer that creates a PopupField of all of my custom DataEntity ScriptableObjects in the project. I registered a RegisterValueChangedCallbackcallback and in the target method I’m setting property.objectReferenceValue manually, but it appears that something else is required because the console log reports that it’s successfully set, although the next time I click the dropdown to change it, the previous value is always null and the debug inspector on the DataEntity in question shows that it’s always null, as it started originally.
Any thoughts on why it isn’t updating the reference? DataEntity is the Base Class, and everything that could ever be put in the drop down is a subclass of it.
All code (besides custom class) is below.
// (c) Copyright Cleverous 2019. All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using Debug = UnityEngine.Debug;
namespace Cleverous.Wafflejar
{
[CustomPropertyDrawer(typeof(AssetDropdownAttribute))]
public class AssetDropdownDrawer : PropertyDrawer
{
private List<DataEntity> m_content = new List<DataEntity>();
private SerializedProperty m_property;
private Type m_sourceType;
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
// load
m_property = property;
AssetDropdownAttribute att = (AssetDropdownAttribute)attribute;
m_content = AllDataEntity<DataEntity>(att);
// find the target object of the property field in the list of items in the project
string pathToCurrentObj = AssetDatabase.GetAssetPath(property.objectReferenceValue);
DataEntity currentTarget = AssetDatabase.LoadAssetAtPath<DataEntity>(pathToCurrentObj);
int currentIndex = Mathf.Clamp(m_content.FindIndex(0, item => currentTarget), 0, m_content.Count);
Debug.Log($"First Obj Ref (index {currentIndex}): {currentTarget}", currentTarget);
// build the popupfield
PopupField<DataEntity> dropdown = new PopupField<DataEntity>(m_content, m_content[currentIndex]) { label = property.displayName };
dropdown.RegisterValueChangedCallback(OnChanged);
// draw
VisualElement container = new VisualElement {name = $"''{att.SourceType.Name}'' Dropdown Selector"};
container.Add(dropdown);
// return
return container;
}
private void OnChanged(ChangeEvent<DataEntity> evt)
{
Debug.Log($"OBJ BEFORE: {m_property.objectReferenceValue}", m_property.objectReferenceValue);
Debug.Log($"New Item: {evt.newValue}", evt.newValue);
m_property.objectReferenceValue = evt.newValue;
Debug.Log($"OBJ AFTER: {m_property.objectReferenceValue}", m_property.objectReferenceValue);
}
private List<T> AllDataEntity<T>(AssetDropdownAttribute att) where T : DataEntity
{
List<T> list = new List<T>();
string[] guids = AssetDatabase.FindAssets($"t:{att.SourceType}");
list.AddRange(guids.Select(guid => AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid), att.SourceType) as T));
return list;
}
}
}