- Home /
how do i draw something in the scene for a property
i'm trying to make an attribute that i can add for anything be it monobehaviour or scriptable object that when it's property is drawn it draws something in the scene, currently the drawing part works but after closing the property drawer the custom OnSceneGui function is not removed from the scene and causes a null exception error (even though there's a null check) here's the most working version:
[CustomPropertyDrawer(typeof(DraggablePoint), true)]
public class DraggablePointDrawer : PropertyDrawer
{
SerializedProperty Prop;
private void OnSceneGui(SceneView obj)
{
//SceneView.duringSceneGui -= OnSceneGui;
Handles.color = Color.green;
int id = GUIUtility.GetControlID(FocusType.Passive);
if (Prop is object)
{
Handles.SphereHandleCap(id, Prop.vector3Value, Quaternion.identity, 1, EventType.Repaint);
Prop.vector3Value = Handles.PositionHandle(Prop.vector3Value, Quaternion.identity);
}
// SceneView.duringSceneGui -= OnSceneGui;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUILayout.PropertyField(property);
if (fieldInfo.FieldType == typeof(Vector3))
{
Prop = property;
SceneView.duringSceneGui -= OnSceneGui;
SceneView.duringSceneGui += OnSceneGui;
}//*/
if (Prop is object)
{
property = Prop;
}
property.serializedObject.ApplyModifiedProperties();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 1;
}
}
I just bumped in the same issue. I can unsubscribe on Selection.selectionChanged. I can monitor if a value changed and I need to update the scene drawer. You can do a trick to unsubscribe when a selection is changed. I had a property with a preview in scene on mouse hover and a toggle that would keep preview on even when mouse is not hovering:
private void SetUpPreview(bool newPreviewValue)
{
if (newPreviewValue != previewAlways)
{
previewAlways = newPreviewValue;
SceneView.duringSceneGui -= _PreviewHandlesInternal;
if (previewAlways)
{
SceneView.duringSceneGui += _PreviewHandlesInternal;
Selection.selectionChanged += UnsubscribeSetUpPreview;
}
}
void UnsubscribeSetUpPreview()
{
Selection.selectionChanged -= UnsubscribeSetUpPreview;
SceneView.duringSceneGui -= _PreviewHandlesInternal;
}
}
And yes, nested methods are a thing, so you can unsubscribe themselves, no problemo.
I wish there would be a way to get all property drawers of a type to ask them to draw from a static method, so you would do that only for active ones.
I bet you should check if
if (Prop)
instead of is object. It's a UnityObject. When it's null, it's not a null really. .NET doesn't treat it as null, but fails to read any fields or call on any members. It has it's == operator overloaded.
Your answer
Follow this Question
Related Questions
Is there a better way to have custom Script icons than Assets/Gizmos 0 Answers
need help with armor customization 1 Answer
Raycasthit2D detect 2 collision in one touch 0 Answers
how to make your character run when you hold shift and w key? 3 Answers
Texture2D in ScriptableObject’s Property drawer experiences serious lag 3 Answers