I’m trying to create a custom inspector with UIToolkit.I create a parent class and two child class in my script,and I declared a List to store instances of the child classes,I want edit the List and it’s members in inspector.
[System.Serializable]
public class DetailRenderer
{
[SerializeField]
protected string detailName;
public string DetailName { get => detailName; set => detailName = value; }
[SerializeField]
protected RenderType detailRenderType;
public RenderType DetailRenderType { get => detailRenderType; }
[SerializeField]
protected ComputeShader cullingComputeShader;
public ComputeShader CullingComputeShader { get => cullingComputeShader; set => cullingComputeShader = value; }
[SerializeField]
protected float2 overallWidthAndHeight = new(0.2f, 0.5f);
public float2 OverallWidthAndHeight { get => overallWidthAndHeight; set => overallWidthAndHeight = value; }
[HideInInspector]
protected int indexOfList;
public int IndexOfList { get => indexOfList; set => indexOfList = value; }
}
[System.Serializable]
public class SingleDetail : DetailRenderer
{
[SerializeField]
private Mesh singleMesh;
public Mesh SingleMesh { get => singleMesh; set => singleMesh = value; }
[SerializeField]
private Material singleMaterial;
public Material SingleMaterial { get => singleMaterial; set => singleMaterial = value; }
[SerializeField]
private List<CustomColorList> singleMeshColorList;
public SingleDetail(string newDetailName)
{
detailName = newDetailName;
detailRenderType = RenderType.Single;
}
}
[System.Serializable]
public class MultipleDetail : DetailRenderer
{
[SerializeField]
private List<Mesh> multiMeshes;
[SerializeField]
private List<Material> multiMaterials;
[SerializeField]
private List<List<Color>> multiMeshsesColoLists;
public MultipleDetail(string newDetailName)
{
detailName = newDetailName;
detailRenderType = RenderType.Multi;
}
}
[SerializeReference]
private List<DetailRenderer> renderList;
And here is my plan to do this:
I create a ListView to display member’s detailName, then create a empty Visual element(I call it detailInfo) for the selected member.
And I create two different VisualElement class for the two child class just like this:
public class SingleDetailVE : VisualElement
{
private TextField detailName;
private EnumField detailType;
private ObjectField singleMesh;
private ObjectField singleMaterial;
private ObjectField detailComputeShader;
public SingleDetailVE(TerrainDetailRenderer.SingleDetail singleDetail)
{
var root = this;
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/TerrainDetailRendererEditor/DetailVE/Single/SingleDetailVE.uxml");
visualTree.CloneTree(root);
detailName = root.Q<TextField>("DetailName");
detailName.bindingPath = "DetailName";
detailType = root.Q<EnumField>("DetailRenderType");
detailType.value = singleDetail.DetailRenderType;
detailType.SetEnabled(false);
singleMesh = root.Q<ObjectField>("SingleMesh");
singleMesh.objectType = typeof(Mesh);
singleMesh.bindingPath = "singleMesh";
singleMaterial = root.Q<ObjectField>("SingleMaterial");
singleMaterial.objectType = typeof(Material);
singleMaterial.bindingPath= "singleMaterial";
detailComputeShader = root.Q<ObjectField>("ComputeShader");
detailComputeShader.objectType = typeof(ComputeShader);
detailComputeShader.bindingPath = "cullingComputeShader";
}
}
(btw,I know the Data Binding in this code is definitely not right)
When I select a member in the ListView,the empty VisualElement should add the right type child class’s VisualElement,here is callback for ListView.selectionChanged
private void OnselectItem(IEnumerable<object> enumerable)
{
detailInfo.Clear();
selectedDetail = enumerable.Last() as TerrainDetailRenderer.DetailRenderer;
if (selectedDetail != null)
{
if (selectedDetail.DetailRenderType == RenderType.Single)
{
Debug.Log("selectedDetail.DetailRenderType = RenderType.Single");
detailInfo.Add(new SingleDetailVE((TerrainDetailRenderer.SingleDetail)selectedDetail));
}
else if (selectedDetail.DetailRenderType == RenderType.Multi)
{
Debug.Log("selectedDetail.DetailRenderType = RenderType.Multi");
detailInfo.Add(new MultipleDetailVE((TerrainDetailRenderer.MultipleDetail)selectedDetail));
}
}
}
And here is my Question:
1.the empty Visual Element(detailInfo) is always nothing to display,even the ListView display member’s detailName right,I guess there must be something wrong in my child class’s VisualElement class
2.how should I bind data for the member of A List?