I've got a panel which sits above my canvas and slides out upon clicking a button. I want to populate this panel with several objects (the number will be determined at runtime). Since the number of objects can exceed the number that would reasonably fit on a single row of the panel, I'd like to be able to scroll down with the mouse to new rows where the remaining objects have been populated.
To achieve this I've put a Scroll Rect and a Mask on the panel, created a child Image with a Vertical Layout Group to hold a series of child panels representing the rows that would hold the objects, and set the Image as the Content of the Scroll Rect.
The issue is that when I try to make one of the row panels a child of the Image object by dragging it to the Image in the Hierarchy, the anchors for the panel coalesce to a single point (the top left of the Image since it is set to Upper Left alignment) and when I try to manually drag the anchors to the appropriate position a box with a red X in it appears and expands in a manner that doesn't seem to correspond to the direction of the mouse.
Is this the right approach, and if so, how can I get this to work?
Thanks!
Related
I am trying to spread out the instantiated objects to fill up the grey area in a grid layout. So far I am stuck at this point where I have all the objects stacked on eachother. I did try a few things but they would make the object not visible. Here is the code I have and two pictures. One of the scene and one of the hierarchy. scene picture hierarchy picture
public class stockSpawner : MonoBehaviour
{
[SerializeField] GameObject stockPrefab;
int x;
void Start()
{
x = Mathf.RoundToInt(scene2Calc.nS);
}
void Update()
{
if (x >= 1)
{
Instantiate(stockPrefab, transform);
x--;
}
else { Debug.Log(x + "this is x value");}
}
}
It seems all of your assets are UI. If you want to create a grid, normally I would say to instantiate the objects and change the transform at which they spawn in a double loop. In one loop you would iterate the horizontal axis of spawning while the other moves the vertical. However, as your setup is all UI, you can use some nifty components to do all the heavy lifting for you.
Attach a grid layout group to the parent object of where you want to spawn all of these UI objects. I would recommend attaching this component to the Panel in your screenshot. I would also recommend changing your installation code slightly as you are working with UI objects. To assure anchoring, rescaling, etc. work, you will want to use Instantiate(stockPrefab, transform, false);. That last parameter is instantiateInWorldSpace, which from the docs,
When you assign a parent Object, pass true to position the new object
directly in world space. Pass false to set the Object’s position
relative to its new parent..
Now getting back to the main portion of your question. If you added the grid layout component to your panel, the objects will now be aligned into a grid. There are various different fields on this component you can change. They are on the docs, but I will also list them here for clarity.
Padding The padding inside the edges of the layout group.
Cell Size The size to use for each layout element in the group.
Spacing The spacing between the layout elements.
Start Corner The corner where the first element is located.
Start Axis Which primary axis to place elements along. Horizontal will fill an entire row before a new row is started. Vertical will fill an entire column before a new column is started.
Child Alignment The alignment to use for the layout elements if they don't fill out all the available space.
Constraint Constraint the grid to a fixed number of rows or columns to aid the auto layout system.
If you properly fill out all of these fields, your UI objects when spawned and childed to the Panel object that has this grid layout component will now not be on top of each other, but will form a grid.
I have set Image Type to Filled because I want to reduce the size of my filling area.
On the left side, you can see my progress bar within the attached image.
Within the inspector, you can clearly see I have set Fill Origin from Top so image size gets reduced from the bottom.
Now one twist I want, I want to reduce an image from both sides top and bottom, I have already played with Image component different values but I can't able to get success.
Overall I want to reduce the size of the image from the top and bottom.
There are 2 ways you can achieve this effect:
You can instead change the Y scale of the image, whilst the Y pivot is 0.5 this will make it shrink from top to bottom, but this will only work if the sprite looks the same even if shrunk down.
If your sprite's shape won't allow for changing the scale like that, you could also split it into 2 sprites at the midpoint and put them next to each other, and then have the top side fill from bottom, and the bottom side fill from top.
I have canvas with vertical layout and 2 elements within (in fact it's element with only recttransform on it, let's call it container). So these 2 containers take a half of the screen by height and stretched by width, ok. How can I place an text element in above container and snap it to the bottom of this container? I tried press bottom button in recttransform widget (also with shift and alt) and it seems it doesn't affect my transform at all
P.s. May be I can use some free plugin instead of default unity components of UI layout?
There are different ways of placing your UI elements
Simply drag and drop it to the bottom where you want it
Use the anchor widget to set the anchoring to bottom with horizontal stretch and hold shift to also set pivot. Then set Pos Y to 0. Set Left and Right to 0.
Assuming you also want other elements in your containers, place a Vertical Layout Group on each container and make sure that your text element is the last child of the container in the hierarchy.
I would also advise you to seek out tutorials on Unity UI anchoring, positioning, scaling, and layout. You need a deeper understanding of how these things interact than you are likely to get from Stack Overflow. Otherwise you will suddenly find that your UI behaves in unexpected ways when rearranged or displayed on a different aspect ratio.
It's fairly easy with Unity UI system. You just need to get used to it. Here are simple steps to accomplish what you want:
Create Text element as a child of that container.
Select your newly created element and edit its RectTransform component values:
2.1. Set both Y axis anchors (min and max) to 0.
2.2. Set pivot value to 0 as well.
2.3. Set Pos Y value to 0 as well.
Now your Text element is anchored at the bottom of the container and its position (and height) is measured from the bottom of the Text element itself.
I've created a core-list which supports ordering items by drag and drop using core-drag-drop and it works.
However, what I want is to force the x coordinate of the dragging item to always be pinned to the left edge of the list. Similarly I don't want to allow the items to be dragged off the top or bottom of the list.
I can't figure out a way to do that with core-drag-drop as it seems hardwired to move the top left of the dragging item to the mouse coords.
Any suggestions?
I have ten labels on a view positioned vertically. I need to evenly space them. Does IB have any type of setting that will do this?
If you select individual labels and drag them around the view, they should "snap" to certain guides around the interface. If you drag an element close to another element it should snap to about 8 pixels away, and that's the standard spacing between elements on the iPhone.
If you want more precise control, you can select an element and use the arrow keys to move it around one pixel at a time.
You can also use the Align Horizontally/Vertically in Container menu items from the Layout menu.
Do the math and then type in the X,Y coordinates. Unfortunately, I think that is the easiest way.
If you are OK using Apple's guideline spacing, dragging one label near another will generate a dashed line at a certain point. Do this for each label below the next, and they will be evenly spaced.