0
\$\begingroup\$

I'm trying to update the sizeDelta of a RectTransform in OnValidate. I'm trying to grab the computed values from a Layout Group.

Here's what I've got:

#if UNITY_EDITOR
        void OnValidate()
        {
            UnityEditor.EditorApplication.delayCall += Resize;
        }

        private void Resize()
        {
            if (this == null) return;
            RectTransform parentRect = (RectTransform)gameObject.transform;
            RectTransform textRect = (RectTransform)tabText.transform;
            textRect.sizeDelta = new Vector2(parentRect.rect.height, parentRect.rect.width);
            layoutElement.preferredHeight = parentRect.rect.height;
        }
#endif

At first this seemed to be working, but it only works the first time OnValidate runs. Subsequence invocations of Resize() sets the sizeDelta to Vector2(0, 0).

I'm wondering what causes this and if there's a way to avoid it. If I remove the delayCall, the values are correct, but I get warnings:

SendMessage cannot be called during Awake, CheckConsistency, or OnValidate

I'd like to do this at edit time since there's no need to compute this stuff at runtime.

\$\endgroup\$
0
\$\begingroup\$

I think you can try something like this, I think it may help but you need to check, if I'm right your delegate contain duplicated methods:

#if UNITY_EDITOR
        void OnValidate()
        {
            UnityEditor.EditorApplication.delayCall += Resize;
        }
        private void Resize()
        {
            if (this == null){
            UnityEditor.EditorApplication.delayCall -= Resize;
            return;
            }
            RectTransform parentRect = (RectTransform)gameObject.transform;
            RectTransform textRect = (RectTransform)tabText.transform;
            textRect.sizeDelta = new Vector2(parentRect.rect.height, 
            parentRect.rect.width);
            layoutElement.preferredHeight = parentRect.rect.height;
            UnityEditor.EditorApplication.delayCall -= Resize;
        }
#endif

the other solution - you can just use direct method without delegate :

#if UNITY_EDITOR
        void OnValidate()
        {
             Resize();
        }
        private void Resize()
        {
            if ((this == null)||tabText.transform == null)
            return;
            RectTransform parentRect = (RectTransform)gameObject.transform;
            RectTransform textRect = (RectTransform)tabText.transform;
            textRect.sizeDelta = new Vector2(parentRect.rect.height, 
            parentRect.rect.width);
            layoutElement.preferredHeight = parentRect.rect.height;
        }
#endif
\$\endgroup\$
4
  • \$\begingroup\$ I appreciate the suggestion! Unfortunately, neither change fixed the issue. delayCall is only executed once, and then the function is removed automatically so there's no need to remove it explicitly like that. Calling resize directly will result in the warnings I mentioned about SendMessage. \$\endgroup\$ Apr 21 '21 at 22:06
  • \$\begingroup\$ OnValidate calling each time when you change field value in inspector I just recreate this script and it is always set the value of textRect.sizeDelata to parent size each time when I put new gameObject with RectTransform into tabText field. So maybe the question is not contain the complete information about your problem. \$\endgroup\$
    – Bogdan
    Apr 22 '21 at 13:58
  • \$\begingroup\$ In your example, are you sure your parent size is controlled by a vertical layout group? That might be the missing piece. \$\endgroup\$ Apr 22 '21 at 17:03
  • \$\begingroup\$ There much more missing pieces nobody would have answer without understanding of your UI structure and class. And it is working fine even if parent size is controlled by any layout group. \$\endgroup\$
    – Bogdan
    Apr 23 '21 at 4:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .