Rebuilding UI Layout from OnValidate
Attempting to call LayoutRebuilder.ForceRebuildLayoutImmediate from OnValidate will result in following warning being thrown into your console: SendMessage cannot be called during Awake, CheckConsistency, or OnValidate UnityEngine.Object:Instantiate(GameObject)
.
We can work around this by utilizing UnityEditor.EditorApplication.delayCall (example script from Udonity):
using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
namespace Varneon.VUdon.Udonity.UIElements
{
[RequireComponent(typeof(LayoutGroup))]
[RequireComponent(typeof(ContentSizeFitter))]
[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class Foldout : UdonSharpBehaviour
{
public bool Expanded
{
get => expanded;
set
{
expanded = value;
toggle.SetExpandedStateWithoutNotify(expanded);
SetContentExpandedState(expanded);
}
}
[Header("Options")]
[SerializeField]
private bool expanded;
[Header("References")]
[SerializeField]
private FoldoutToggle toggle;
private void SetContentExpandedState(bool expanded)
{
gameObject.SetActive(expanded);
LayoutGroup[] layoutGroups = GetComponentsInParent<LayoutGroup>(true);
foreach (LayoutGroup layoutGroup in layoutGroups)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(layoutGroup.GetComponent<RectTransform>());
}
}
#if UNITY_EDITOR && !COMPILER_UDONSHARP
private void OnValidate()
{
UnityEditor.EditorApplication.delayCall += OnValidateDelayed;
}
private void OnValidateDelayed()
{
if (this == null) { return; }
if (toggle)
{
toggle.Foldout = this;
toggle.SetExpandedStateWithoutNotify(expanded);
}
SetContentExpandedState(expanded);
}
#endif
}
}
No Comments