unity instantiating multiple objects on the same position. I would like to spread them out - unity3d

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.

Related

Unity3d. UI elements snapping/anchoring

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.

overlapping elements in grid layout

In my game i add child object prefabs to a grid layout dynamically,
But the problem is when i do this the child objects overlap:
If i do this without code, the problem disappears but i want to do it through code.
instantiation code is fairly simple:
go = Instantiate(CardPrefab) as GameObject;
// go.GetComponent<Image>().sprite = card.GetSprite();
go.GetComponent<Image>().sprite = GC.GetSprite(1, card.GetIndex());
go.transform.GetChild(0).gameObject.SetActive(true);
go.transform.SetParent(GameObject.Find("Player1ScrollPannel").transform);
what is the solution?
there is nothing attached to my card prefab, just an image and a button as a child:
Note: I haven't really played with layout groups, but...
70 pixels times a scale of 8.34 results in a final size of 583.8, but you're asking your layout group to arrange things in 106 pixel-wide cells.
In pulling up Unity and shoving a few images with a high scale value into a layout group...I get the same behavior. You either need to remove the scale (1,1,1) or change the layout cell size.

How to move a prefab to the desired position in scrollview in unity

I have a prefab consists of two buttons horizontally.I am able to get list with those prefabs but now I need to swap positions of the clone prafabs.For example I have three clones now i have to move third clone to fist or second position.How do i get that?
here is how i am getting list
var WordGroup = Instantiate(DeletePrefab);
SelectedWordsPrefabModel prefabModel = WordGroup.GetComponent<SelectedWordsPrefabModel>();
prefabModel.SelectedWordBtn.GetComponentInChildren<Text>().text = word.Word;
WordGroup.transform.SetParent(Content);
The easiest way is to use some layout component, e.g. Horizontal Layout Group, to position your children automatically and just to set the sibling index instead of calculating positions manually.
someGameObject.transform.SetSiblingIndex(newIndexNumber);
This reorders the children in the hierarchy view, which is used by layout components. Indexes are counted zero-based, so set the index of the third child to 0.
See also: Auto Layout reference

Unity Resizing Dropdown Dynamically

I have a dropdown list on a filter panel which needs to stretch dynamically to fit the content as shown:
I have tried several content size fitters but cannot find anything, If possible I would like to set a max width it can expand to then truncate everything longer than that, I would also like it to expand only to the right with a right pivot point. I have found a similar example here: https://forum.unity3d.com/threads/resize-standard-dropdown-to-fit-content-width.400502/
Thanks!
Well. Lets start with the code from that Unity forum thread.
var widest = 0f;
foreach (var item in _inputMines.GetComponentsInChildren<Text>()) {
widest = Mathf.Max(item.preferredWidth, widest);
}
_inputMines.GetComponent<LayoutElement>().preferredWidth = widest + 40;
We want to have a max-width allowed, so any content longer than this will be truncated. So let's add that variable:
var maxWidth = 250f;
//or whatever value; you may wish this to be a property so you can edit it in the inspector
var widest = 0f;
foreach (var item in _inputMines.GetComponentsInChildren<Text>()) {
Now we use the smaller of the two width values. Then apply it to the content layout:
}
widest = Mathf.Min(maxWidth, widest);
_inputMines.GetComponent<LayoutElement>().preferredWidth = widest + 40;
The +40 should be retained because that deals with the scrollbar. Your maxWidth value should be chosen to account for this.
Finally we want the longer items to get cut off nicely.
Give each dropdown item a Rect Mask 2D component (Component -> UI -> Rect Mask 2D). The template object exists in the scene hierarchy before the game is run, just disabled. You can just add the component to the parent transform, the one with the image (so the text is clipped).
You'll need to make sure that the mask covers the same width as the image graphic and expands along with it, possibly slightly shorter on the X direction so the text gets cut off before the image border is drawn. This should happen automatically, but you will need to check and possibly make some alterations to the template object. Alternatively you can use an Image Mask, but you'll have to play with that one yourself, but it will allow for non-rectangular clipping.
That's it!

Can't get vertical layout group with scrolling working

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!