- Home /
Horizontal Layout Group padding update via script
I have UI DropDown combo box, constructed from layout groups, buttons and panels and i want to animate combobox elements (that basically are buttons placed in Layout Group) hide and show act. Idea was to change their anchored position by Layout Group padding (since i can't change position by rectTransform) and during test (that means changing padding value in inspector), everything went find, but when i tried to change padding value via script, although value HAS changed in inspector, RectTransform didn't changed. Any change on inspector, and recTransform update to value passed by script. I did some tests with simple script:
public HorizontalLayoutGroup sterringLayout;
void Update()
{
sterringLayout.padding.top += 1;
}
In inspector values of sterringLayout padding gone crazy, but RectTransform did not change.
What is cause of that? Is there workaround?
Hello, I just have the same problem, did you find solution?
Yes, i did! I have aborded trying to change padding via script. The same effect i have achieved by changing RectTransform.sizeDelta of the same object, to which LayoutGropu is attached
Oh, nice then. I can't change the sizeDelta because RectTransform driven by Horizontal Layout Group =(
Answer by JoshuaMcKenzie · Jan 25, 2016 at 12:25 AM
@Polak149 The reason is similar as to why you can't directly modify the Vector3 of a transform.position.
Doing so would update the state of the contained object (Vector3 for position... or RectOffset for Padding). while the value is getting updated, the containing object (Transform for position or HorizontalLayGroup for the padding) would have no idea that the contained object was updated, it was never told. The container only keeps a reference of the object, not it's state. So when you did this, sterringLayout.padding.top += 1;
,sterringLayout is still pointing to the same object so it doesn't think its changed and thus doesn't call LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
(which it calls internally).
Simply grabbing the object updating it and passing it back in won't work either (unlike it does with Vector3 on transform.position). because padding is a RectOffset class while postion is a Vector3 struct.
RectOffset tempPadding = sterringLayout.padding;
tempPadding .top += 1;
//this won't work as tempPadding and sterringLayout.padding are still
// both pointing to the same reference and thus still the same object.
sterringLayout.padding = tempPadding ;
internally Layoutgroup uses the .Equals() to compare the old value versus the new value. and since both sterringLayout.padding and tempPadding reference the same object the .Equals() will return true.
There are two ways you can get the Layoutgroup to update correctly.
create a new RectOffset that copies the old offset, update it then pass it back.
RectOffset tempPadding = new RectOffset(
sterringLayout.padding.left,
sterringLayout.padding.right,
sterringLayout.padding.top,
sterringLayout.padding.bottom);
tempPadding.top += 1;
sterringLayout.padding = tempPadding;
since this tempPadding used the "new" operator it's reference will be different and thus the layout will update correctly.
manually call LayoutRebuilder
void Awake()
{
RectTransform rect = GetComponent<RectTransform>();
}
void Update()
{
sterringLayout.padding.top += 1;
LayoutRebuilder.MarkLayoutForRebuild(rect);
}
since you know for a fact that the RectTransform needs to be updated you can forcibly call this function, doing what the SetProperty would have done for spacing.
Both options work but its reccomended to do the first option so that the LayoutGroup class manages the updating as its meant to do. The second option looks cleaner but if the Unity dev's happen to change LayoutRebuilder then you'd have to come back and update your code too.
This makes all sense! I had this problem like an hour ago and I predicted it was something related with that. THAN$$anonymous$$ YOU @Joshua$$anonymous$$c$$anonymous$$enzie. Fixed here! Thanks a lot ;)
Answer by samra2494 · Mar 13, 2019 at 10:27 AM
i was stuck in this problem... thanks a lot for your answer @JoshuaMcKenzie It works for me :) good Explanation :)
public RectTransform Needle1;
RectOffset rect;
public void Method()
{
rect = Needle1.GetComponent<VerticalLayoutGroup>().padding;
Needle1.GetComponent<VerticalLayoutGroup>().padding.left = 0;
LayoutRebuilder.MarkLayoutForRebuild(Needle1);
}
Your answer
Follow this Question
Related Questions
uGUI Vertical Layout Group stretching objects 2 Answers
Question regarding VerticalLayout - list is not populating correctly except during Start()! 0 Answers
how to extend the GUILayout scrollview's function? 0 Answers
What is the LayoutElement.FlexibleWidth/FlexibleHeight above 1 for? 0 Answers
How do I code a custom LayoutGroup? 0 Answers