How do I bind a float array with Uxml Attribute Description in Unity UI toolkit?

483 Views Asked by At

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

0

There are 0 best solutions below