0

I'm trying to make a custom inspector in Unity which takes in a float[] array and plots it as a line graph.

I'm making a BindableElement called "LineGraph2D" to do just that which sits as an element in UI Builder.

I think I'm having particular trouble with the Uxml traits as I can't find any examples of how this is meant to be done with arrays. I'm trying to use UxmlTypeAttributeDescription<float[]> to do so.

Any ideas on how to get this working?

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

public class LineGraph2D : BindableElement
{

    public new class UxmlFactory : UxmlFactory<LineGraph2D, UxmlTraits> { }
    public new class UxmlTraits : BindableElement.UxmlTraits
    {
        // TODO I want this to be an array bound by the user... not sure how this works.
        UxmlTypeAttributeDescription<float[]> array = new UxmlTypeAttributeDescription<float[]> { name = "array-data" };

        public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
        {
            base.Init(ve, bag, cc);
            var line2D = ve as LineGraph2D;
            // Unity Doesn't like this line below (Error: can't assign to property as its read only)
            line2D.arrayData = array.GetValueFromBag(bag, cc);
        }
    }

    VisualElement lineGraph;

    float[] array;

    public float[] arrayData => array;

    public LineGraph2D()
    {
        lineGraph = new VisualElement();
        lineGraph.generateVisualContent += DrawArray;
        Add(lineGraph);
    }

    void DrawArray(MeshGenerationContext ctx)
    {
        var painter = ctx.painter2D;
        painter.strokeColor = Color.red;
        painter.fillColor = Color.red;
        painter.lineWidth = 1f;

        painter.BeginPath();
        for (int i = 0; i < 100; i++)
            // TODO change for array data (and scale etc)
            painter.LineTo(new Vector2((float)i * 10f, 100f * Random.value));

        painter.Stroke();

    }

}

Thanks in advance and sorry for my code stinks!

best, Rob

derHugo
  • 83,094
  • 9
  • 75
  • 115
maddogedge
  • 23
  • 2
  • well your `arrayData => array;` is a readonly property .... have you tried just setting the **field** `array` instead? Also this `array.GetValueFromBag(bag, cc)` seems to return a `Type` .. not a `float[]` ... – derHugo Jan 10 '23 at 10:59
  • Wouldn't you rather go through [`Bind`](https://docs.unity3d.com/Packages/com.unity.ui@1.0/api/UnityEditor.UIElements.BindingExtensions.html#UnityEditor_UIElements_BindingExtensions_Bind_UnityEngine_UIElements_VisualElement_SerializedObject_) ? – derHugo Jan 10 '23 at 11:10
  • Since posting I think I don't want uxml for the array. As you say, just straight up Bind could be better for me. I'll look into that thanks. – maddogedge Jan 10 '23 at 11:26
  • How would I use Bind() here? – maddogedge Jan 10 '23 at 11:43

0 Answers0