Combine text and buttons in scroll rect - unity3d

I'm attempting to create a scrollable UI object that has 2 sections with one on top of the other: a text section and a button list section. My main problem is that the text and list of buttons change in size depending on what content the player is viewing.
It seems that just throwing the text and buttons into an empty UI object doesn't work, because the empty game object does not take on the size of its children, and since the empty object does not have its own size, scrolling through its contents is not possible.
Is there maybe an element that I am not aware of that could help me out?

Here's the setup I use for Scroll. It seems you are missing the third object, the content object. It is what decides the physical size of your content size using a Content Size Fitter and a Layout Group. I decided to include the entire setup just in case you are missing something else.
Parent Object (Mask OR Rect Mask 2D) - Object that is the visual bounds of your UI
-> Scroll Object (ScrollRect) - Actual scroll component that drives the UI scroll
-> Content Object (Horizontal OR Vertical Layout Group AND Content Size Fitter) - Is the parent of your actual data in your scroll
To explain this a bit better, the Mask is used when you have a nonrectangular asset that you still want to be your max viewing bounds. Anything outside of this Mask will not be rendered. A Mask is more expensive than a Rect Mask 2D, so if your viewport is a square or rectangle, then use the 2D component.
The Scroll Rect is the driver of the scrolling of UI elements in Unity. Make sure to check the box if it is horizontal or vertical. I assume in your use case you are using vertical. Make sure to set the Content field to be the child of this object and the Viewport to be the parent (the mask).
The Content Object has two components on it. The first being the Content Size Fitter which will force this object to be the size of its content. If your scroll is a vertical scroll, set the Vertical Fit to Preferred Size and leave the Horizontal Fit to be Unconstrained size. If it is the opposite, then set the opposite of what I just said. The other component on this object is a Horizontal Layout Group OR a Vertical Layout Group. The difference being which direction your scroll is. The checkboxes in the settings of this object matter quite a bit. Check out the docs on what each one does.
If you attach the components as I specified and set the proper settings on the layout group, you should be able to have as many dynamic objects with variable size swapping between text and buttons.
If you have any other questions let me know. UI can be a bit daunting at first but once you figure it out, it gets much easier.
Edit:
To achieve an object that can change size with a text object and a button, you will need to use a combination of content size fitters and layout groups.
Here is an example hierarchy
Here is the result
Using a combination of the layout groups and content fitters forces the container the text is in to be the size it needs to be. If you are making these assets static meaning none of it is data-driven at runtime, then this should work right away. If you are changing this data at runtime, you will need to use LayoutRebuilder on the parent objects to assure that the layouts rebuild properly. Let me know if you have questions.

Related

Unity3D is sizing icons differently

Bellow is a section of my games UI made in Unity3D. I was adding the icon on the left side when I realized that it was much larger than the icon in the middle so I went to give them a similar size. According to the Rect Transform of these objects the icon in the center of the screen is larger than the one on the left which again according to the Rect Transform is the smallest icon on the screen.
Does anyone know of why this might be? I don't quite understand Unity's units of measure. These icons are nested in many game objects with Layout Groups, Content Size Fitters, and Layout Elements. So I am not exactly sure what is retentive to these icons but I will show their parents and grand parents here.
If There is anything else I can you would need to know I can post more info.
You don't show the scale of the rect transforms so I assume they are the same.
Layout groups and content size fitters will (if you allow them to) change the size of the GameObject to make it fit a certain space, that is what they are for! This will then override the size that you have manually given to the GameObjects.

The VLG component does not expand regardless of the length of the child

This is my hierarchy in the Unity scene:
Vertical Layout Group
ScrollView (Horizontal)
Text (Very long)
I set the graphics to work perfectly in portrait mode with mobile device screens. But when I use the graphics on a tablet, or when I rotate the device, I have to enlarge the elements, and here the problem arises.
I can't find the correct way to expand the elements, I want many ScrollViews in the Vertical Layout Group, and I want to be able to scroll horizontally to view the texts inside, that's what I'm asking.
The question is convoluted and complex to explain, I explain it in three different ways (talking about the same thing, so they may seem similar), you choose which one is more understandable to you:
Explanation 1
The Vertical Layout Group expands autonomously, covering a large part of the screen.
The problem arises when I have to decide how to enlarge the ScrollView, I cannot use the anchors because they are replaced by the Vertical Layout Group, and I cannot use the "Control Child Size" and "Child Force Expand" option, because it would expand beyond the Vertical Layout Group, if the text component inside was longer, thus making the Scroll useless.
I want the ScrollView to expand only within the limits of the Vertical Layout Group, and therefore not be affected by the length of the internal text component (so that I can scroll it) (PS. I cannot use a Layout Element, because the text can vary both horizontally and vertically, and because the ScrollView is equipped with another Vertical Layout Group (I need it to manage the vertical development of the text, if it want to expand in height))
Explanation 2
I would like the ScrollView to expand horizontally until it touches the limits of the Vertical Layout Group.
This I would be able to do by enabling "Control Child Size" and "Child Force Expand".
However, I would like one more thing, which is that the ScrollView does not expand beyond the limits of the Vertical Layout Group. This problem is caused when the Text component (of variable size) will be longer than the length of the Vertical Layout Group.
I would therefore like the ScrollView to expand into the Vertical Layout Group, without being influenced by the size of the child.
Explanation 3
Trying to seem clearer, to enlarge the ScrollView to the limits of the VLG, I have to enable both "Control Child Size" and "Child Force Expand" (I can't use anchors, because it's the same VLG that replaces them with its own), but putting "Control Child Size", if the child Text were to be longer than the VLG, it would make the ScrollView enlarge (and I don't want this to happen! otherwise the ScrollView, if it were as long as its component, would make no sense! I want that the ScrollView stretch to the limits of the VLG, but don't exceed them!)
Enabling "Control Child Size" and "Child Force Expand" in the VLG made the ScrollView dependent on the length of the child. However, by also enabling "Control Child Size" in an additional VLG in the ScrollView, the problem vanished. In practice, the ScrollView stops depending on the child, so it is it who controls, instead of being controlled.
After the clarification, I believe I understand what you'd like to achieve. If this is not what you'd like, please correct my implementation so I can answer the question properly.
Here is the hierarchy I have set up.
Here is the UI working with the current setup.
As the UI is rather extensive, if you make any changes at runtime, you will need to make calls to rebuild the layout if you happen to change the text's length. The scroll will not change properly in a single update cycle. To update it at runtime, you can make a call to LayoutRebuilder.ForceRebuildImmediate while passing in a proper RectTransform for rebuilding.
I may have misunderstood the question, but is this solved by just changing the anchor points of the ScrollView to fit the Vertical Layout Group (no "Control Child Size" and "Child Force Expand" needed):
Using Anchor points to stretch to fit the parent object:

Layout issues in Unity

I have a Vertical Layout Group with a Content Size Fitter, with children a TextMeshPro and a ScrollView.
(The TextMeshPro is not a problem, I only put it to show that I needed a Vertical Layout Group, so let's forget that)
Inside the ScrollView I have another Text element. This Text element expands both vertically and horizontally. I want the horizontality to be scrolled by the ScrollView and I want the ScrollView to adjust to the height.
So I want the ScrollView to be the same height as all of its internal elements. this is my goal. I don't want a scripted solution, I want to be able to do it directly from the hierarchy, where you define the layout of all elements.
However I am not able to do this, my idea was to put the Vertical Layout Group with a Content Size Fitter in the ScrollView, but if I do, I can no longer scroll the text horizontally, as it is constantly realigned based on the alignment defined in the Vertical Layout Group.
ps. At first you might think, but a text with a horizontal Content Size Fitter does not stretch vertically, what need is there to enlarge the ScrollView based on the height of the text? In reality I don't really use the Text component, I use a similar component created specifically for particular fonts, which also expand the text vertically, for this I need that the height of the ScrollView dynamically adapts to the child components, but I repeat, with a Vertical Layout Group, then I can't scroll anymore.
Solutions?
I had done well the layout system. Disable Pixel Perfect on Canvas fix the problem of the text realignment.

How do I set specific y position, width and height without diving into code?

A designer I'm working with wants to have a UIImageView be at a specific y position, with a specific width/height depending on the iphone size. I've done research and I haven't been able to find anything online that allows me to do so with constraints on the story board. I want to avoid having to use code because throughout the rest of the app there are a lot of similar situations. In the past I've made different storyboards for each phone size to accommodate for the specificity our clients request, but I want to avoid doing this because it feels like bad practice. Is this even possible?
This can be completely handled in the Interface Builder. Follow the steps below.
1) Add your UIImageView to the ViewController
2) Set constraints for Width, Height, Vertically Align and Horizontally Align
3) You can adjust the Y position in the Size Inspector of the view.
4) Now switch to Assistant Editor and choose 'Preview' and add different screen sizes to see the auto layout in action.
All of this will set a static image size of 250x200, horizontally centered, and vertically at 1/4 of the screen height.
Little-known capability of constraints are that you can set view positions, or in your case sizes, by way of ratios against other views.
With just your image view selected, the tie-fighter :) constraints button lets you specify absolute positions & sizes: do that to set your desired y-position. But then select both your image view and its enclosing parent view, then the pop up for that same button now enables the equal height/width buttons. Add those constraints and then edit the constraint to change the 1:1 ratio to whatever ratio you need.
Excuse my lack of screenshots, posting from my phone.

Expanding content within UIScrollView

I'm building a cell-based game that essentially works like dominoes: you start with one tile in the center, then connect additional tiles to it that can branch out in all directions. I have my game table all set up and working great... now I just need to make it scroll to accommodate the expanding content.
So, this doesn't seem to fit easily into a UIScrollView's built-in behavior. For one thing, cells expand in all directions – potentially going into the negative coordinate space of the UIScrollView. As far as I can tell, UIScrollView does not allow an actual CGRect with size AND origin to be defined for the scrolling content area. It appears you can only define a width and height for the content area that extends from point (0,0). Is this true, or am I missing something?
Assuming my understanding of the content area limitations are correct, how would one ideally handle this problem? My go-to idea would be to shift all subviews into positive coordinate space as the game board expands, then update the ScrollView's contentOffset property to counter the shift and make the transition invisible. I just want to make sure I'm not reinventing an inferior wheel before I start developing this.
Thanks in advance for any and all ideas!
I believe your idea is the good one, every time a tile is added, you may need to adjust your content view in order to be able to center on the tile that just was added.
Hence if this is "backward" (-x or -y) and your on top of your view (or nearly), you'll have to extend your contentView (surely the same way you do for +x, +y) and thus, adjust every of your tiles with the translation you did to your contentView's down-right corner.
Following up... yep, that did it. I set up the display so that it redraws the grid of cells from the upper-left corner. Whenever a new row or column of cells is added to the top or the left, the UIScrollView's contentOffset shifts by the newly added pixels to hide the change in content position.