How to add OnRectTransformDimensionsChange prgramatically

Hello,

How do I programmatically add a listener for the OnRectTransformDimensionsChange event to a UI object that has a RectTransform component? Something like:

public class ExampleResizeHandler : MonoBehaviour
{
    public GameObject myGameObject;

    private void MyResizeHandler()
    {
        Debug.Log("Called MyResizeHandler");
    }

    void Start()
    {
        myGameObject = GameObject.Find("MyGameObject");
        RectTransform rectTransfrom = myGameObject.GetComponent<RectTransform>();

        // The next line is not valid syntax: what should it be?
        rectTransfrom.onRectTransformDimensionsChange.AddListener(MyResizeHandler);
    }
}
1 Like

Annoyingly the MonoBehavior docs (even for the latest 2020.2 version) does not contain this information. I reported it missing because I believe it belongs there.

In other news, this is not an event the way a Button.onClick event is, at least as far as I can tell from actually using it in Unity2020.5f1, and it works fine for me.

It is actually just a simple old MonoBehavior method, just like OnEnable() or what-have-you. Just make a function named properly:

and you should get callbacks:

    private void OnRectTransformDimensionsChange()
    {
        Debug.Log("Called MyResizeHandler");
    }

CAUTION: it does seem to be called multiple times when poking and dragging the RectTransform from the inspector, so try not to do too much work in that callback.

3 Likes

That’s great thanks and works well for UI objects created at design time. Ideally I want to create some UI objects at runtime. Something like:

public class RectTransformEvents : MonoBehaviour
{
    void Start()
    {
        GameObject runtimePanel = new GameObject("RuntimePanel");
        runtimePanel.AddComponent<CanvasRenderer>();
        runtimePanel.AddComponent<RectTransform>();
        // Other initialisation of the new RuntimePanel...
    }

    // How to get this invoked when RuntimePanel is resized?
    void OnRectTransformDimensionsChange()
    {
        Debug.Log("OnRectTransformDimensionsChange");
    }
}

How do I listen for OnRectTransformDimensionsChange() on the new RuntimePanel object? Thanks.

Same way you might expect: stick a monobehavior on it that contains that callback!!

1 Like

Great. I understand now. For the benefit of others here’s a minimum snip solution. First create a script that handles the RectTransform changes. I’ve called it “HandleRectTransformResize”.

public class HandleRectTransformResize : MonoBehaviour
{
    // Called when dimensions of a RectTransform change
    void OnRectTransformDimensionsChange()
    {
        Debug.Log("OnRectTransformDimensionsChange");
    }
}

Next create a script that creates new GameObjects at runtime. Attach the previous script to any objects that need to handle changes to the RectTransform dimensions.

public class AddGameObject : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // Creat a new GameObject at runtime
        GameObject newGameObject = new GameObject("Demo Game Object");

        // Add a RectTransform component to the new game object
        newGameObject.AddComponent<RectTransform>();

        // Attach the HandleRectTransformResize script to the new game object.
        newGameObject.AddComponent<HandleRectTransformResize>();
    }
}

Thanks for the support and hope that helps others.

4 Likes