Hi,
I have made a custom Graphic UI element. The element works fine and if I change one of the parameters in the inspector the element is updated correctly.
The size of this element is related to the panel in which it is located and this is the only problem.
If I change the recttransform of the panel, like changing the anchors, The ui element is not resized but only translated because the Onvalidate function is not called when the recttransform is changed.
I do not know how to make the element update when I resize the panel in the inspector. Any idea?
When you said a custom Graphics UI element, do you mean you actually subclassed the Graphic class and created your own class? If that’s the case, how about overriding OnTransformParentChanged? How do you actually “draw” your element? The UI system uses the OnFillVBO callback to actually fill the object. The object should be invalidated automatically when a parent has changed (unless you overridden one of the necessary callbacks without calling the base implementation).
We can’t really help you without any concrete information on what your custom Graphics UI element does.
So what I did is like this (cut the code because is complicated and I think we will lose focus)
The Graphic component get as input a Vector2 array with the coordinates of the point of the mesh
[RequireComponent(typeof(CanvasRenderer))]
public class MyUI : Graphic
{
[SerializeField] private Vector2[] points;
// other variables
protected override void OnPopulateMesh(VertexHelper vh)
{
// Set the mesh
}
public void SetMyUI(Vector2[] InputPoints)
{
points = InputPoints;
SetVerticesDirty();
}
}
In the panel there is a controller script that gets several inputs and compute the points of the mesh. To verify that everything is working fine I call the controll routine also in OnValidate(). Like this
public class myUIController : MonoBehaviour
{
[SerializeField] Variable1;
[SerializeField] Variable2;
[SerializeField] Variable3;
...
private void Start()
{
ComputePoints();
}
private void OnValidate()
{
ComputePoints();
}
private void ComputePoints()
{
//Do all the computation needed
MyUIObject.SetMyUI(InputPoints);
}
}
When I change Variable1, Variable2, etc in the Inspector the MyUIObject is updated correctly because OnValidate is called but if I change the RectTransform of the panel to which myUIController is attached nothing is happening because OnValidate is not called. Does this explain better what I’m doing?
But OnPopulateMesh is supposed to update the representation of your element. Why do you call your ComputePoints manually outside of the whole UI system? As I said when the parent is changed the object is automatically invalidated and updated. OnValidate should not call “ComputePoints” but simply call SetVerticesDirty or one of the other dirty methods depending on what aspects of the graphic you have changed. Once it’s marked as dirty it should be updated automatically. So your calculation should be inside OnPopulateMesh
Thanks. the reason why I did this (other than It’s my first try with a Graphic element) is because I create several MyUIObjects as child of my panel, and only one of the input variables change between them while the others are the same. So I though that It was easier to set all the inputs in a controller instead of having to copy the input variables for each of the MyUIObjects. Now it doesn’t sound like a great idea…