Hello. I want to use a scrollview but I cannot find one example how of how to use it programmatically. can anyone show me how to add items to it. I am so frustrated. thanks bye.
To add to a scroll rect or scroll view you add new objects as children of the content object.
If you want a scrolling list, then you need to have a vertical layout group, with your list items as children of that.
Ok thanks for the advice. I tried it on my own but cant get it to work. Unity ui is so hard for me.
Image sv = GameObject.Find(âScrollViewâ).GetComponent();
BoxCollider2D boxCollider2D = sv.gameObject.AddComponent();
boxCollider2D.size = new Vector2(
sv.gameObject.GetComponent().sizeDelta.x,
sv.gameObject.GetComponent().sizeDelta.y
);
VerticalLayoutGroup glg = sv.gameObject.AddComponent();
GameObject go1 = new GameObject(âContacts 22â ); // each invididual contact panel on the list
go1.transform.SetParent(sv.gameObject.transform);
RectTransform trans11 = go1.AddComponent();
trans11.anchoredPosition = new Vector2(0, 0);
Image im = go1.AddComponent();
im.color = Color.red;
Set_Height(im, 40.0f);
This does not work, what am I doing wrong, thanks.
The best thing to do is set it up in the editor first, make sure it looks right, then set it up in code the same way.
why isnt there just a sample of this on the internet. I can make it in the editor by adding a scrollview the adding anything I want, thats simple. What about making it programmatically. Unity doesnât have enough programming documentation, just how to make this in an editior. I have a dynamic list of contacts that changes when my project loads. Thats why I am doing this programmatically.
To expand on some previous feedback, if I were in your situation, Iâd create the panel with the vertical layout group. Iâd then have 1 prefab setup to be instantiated with the new data. When I wanted to add new data, Iâd create a new game object from the prefab, add it to the panel(scrollview) and give whatever specific data it needs at that time.
If you want to try something like that & see how it goes, you could write back here (whether you succeed or fail, doesnât matter) with your updated code and code tags
What exactly is it thatâs not working? I have been using it in a custom editor window (programmatically). My case gets a little odd because I technically have two scroll views. I am showing some tabular data so Iâm showing a header and data below⌠I wanted to scroll both horizontally but only scroll the data vertically, so I actually sync the âxâ value of the header position with the âxâ value of the data position. The âyâ value of the header position is always zero. So I basically used something like this:
public class TableDataComponent : EditorComponent
{
private Vector2 RecordScrollMarker = new Vector2(0, 0);
private Vector2 LayoutScrollMarker = new Vector2(0, 0);
private static Dictionary<Type, Action<IField>> OutputResolvers = new Dictionary<Type, Action<IField>>();
private static int CellWidth = 150;
private List<DataRow> _data;
static TableDataComponent()
{
OutputResolvers.Add(typeof(string), GenerateStringField);
OutputResolvers.Add(typeof(int), GenerateIntField);
OutputResolvers.Add(typeof(Guid), GenerateGuidField);
OutputResolvers.Add(typeof(float), GenerateFloatField);
}
public TableDataComponent(List<DataRow> data)
{
_data = data;
}
public override void RenderContent()
{
if (_data == null || _data.Count == 0)
return;
GUILayout.BeginScrollView(LayoutScrollMarker, GUIStyle.none, GUIStyle.none);
GUILayout.BeginHorizontal();
var firstRow = _data.First();
EditorGUILayout.LabelField("", GUILayout.Width(60), GUILayout.MaxWidth(60));
foreach (var field in firstRow.Fields)
{
EditorGUILayout.LabelField(field.FieldName, GUILayout.Width(CellWidth), GUILayout.MaxWidth(CellWidth));
}
GUILayout.EndHorizontal();
GUILayout.EndScrollView();
RecordScrollMarker = GUILayout.BeginScrollView(RecordScrollMarker);
LayoutScrollMarker = new Vector2(RecordScrollMarker.x, 0);
for (var i = 0; i < _data.Count; i++)
{
GUILayout.BeginHorizontal();
GUILayout.Button("Edit", GUILayout.Width(60), GUILayout.MaxWidth(60));
var record = _data[i];
for (var j = 0; j < record.Fields.Count; j++)
{
var currentField = record.Fields[j];
var resolver = OutputResolvers[currentField.DataType];
resolver(currentField);
}
GUILayout.EndHorizontal();
}
GUILayout.EndScrollView();
}
private static void GenerateStringField(IField field)
{
var target = field as Field<string>;
EditorGUILayout.LabelField(target.Value, GUILayout.Width(CellWidth), GUILayout.MaxWidth(CellWidth));
}
private static void GenerateGuidField(IField field)
{
var target = field as Field<Guid>;
EditorGUILayout.LabelField(target.Value.ToString(), GUILayout.Width(CellWidth), GUILayout.MaxWidth(CellWidth));
}
private static void GenerateIntField(IField field)
{
var target = field as Field<int>;
EditorGUILayout.LabelField(target.Value.ToString(), GUILayout.Width(CellWidth), GUILayout.MaxWidth(CellWidth));
}
private static void GenerateFloatField(IField field)
{
var target = field as Field<float>;
EditorGUILayout.LabelField(target.Value.ToString(), GUILayout.Width(CellWidth), GUILayout.MaxWidth(CellWidth));
}
}
Thereâs a lot of code there you donât need and itâs a little wonky as this was all written for testing purposes and you wouldnât have all of the types, but it gives you an idea (example) of scroll views working.
Thanks Dustin-Horne but that code is still very differnent from what I am doing.
Thanks methos5k that sounds like what I am doing below. can you please look at my code and tell me if I am doing anything wrong, but Image that I add to a gameObject is not showing up I donât know why. How can unity expect people to use their UI without any Documentation on how to use it programatically.
Image sv = GameObject.Find("ScrollView").GetComponent<Image>();
BoxCollider2D boxCollider2D = sv.gameObject.AddComponent<BoxCollider2D>();
boxCollider2D.size = new Vector2(
sv.gameObject.GetComponent<RectTransform>().sizeDelta.x,
sv.gameObject.GetComponent<RectTransform>().sizeDelta.y
);
VerticalLayoutGroup glg = sv.gameObject.AddComponent<VerticalLayoutGroup>();
GameObject go1 = new GameObject("Contacts 22" ); // each invididual contact panel on the list
go1.transform.SetParent(sv.gameObject.transform);
RectTransform trans11 = go1.AddComponent<RectTransform>();
trans11.anchoredPosition = new Vector2(0, 0);
Image im = go1.AddComponent<Image>();
im.color = Color.red;
Set_Height(im, 40.0f);
Of course you can do it all in code. However, you could skip the part for creating the scroll view in code, as well as the game object with image for each contact panel, I guess they are.
The scroll view panel could be created in the scene once and its contact panels can be added from a prefab, as I tried to say before.
Anyways, back to the question, I am not sure why your code is not working. Does it have any errors or anything?
Plus, itâs hard to read that⌠I mean, it looks like youâre adding a layout group, but do you just do that once? I mean, Iâm not sure how you add your âdynamic contactsâ.
Iâm certain if you google you can find an example of a dynamically populated list. Unity also has some of the best documentation of any game engine Iâve used, including the UI. Thereâs scripting API entries for every component weâve mentioned.
No one is questioning why youâre doing this programmatically, but thereâs no reason to do literally everything in code. You can set up almost all of it in the editor (because itâs way easier), and then only code the dynamic portions. If you have a list that gets filled dynamically, create the entire list UI in the editor, make a âlist itemâ prefab in the editor (make sure it looks right in the list in the editor), and then spawn the list item prefabs into the list with code when the game loads.
Hey Thanks. I got it partially working. I kinda did what you said jeffreyschoch. I couldnt add content to the scrollview at all, so I figured out that I could add stuff to the content element of the scrollview in the editor. So I got a handle on the panel from inside my code and added some images to it. It looks ok for now. The problem, is that if i add alot of images to the panel in the scrollview, the content of the panel will not overflow and the scrollbar doesnt work when I do this. I want to have a large list of items and be able to scroll down them. I tried a content size fitter on my panel bu that didnt work. I have one more problem when I add a list of images to the panel in the scrollview, the images 0 to 20 for example donât start at the exact top of the panel, they start somwhere in the middle. I have a pic to illustrate this. See where it says contact to that starts at the top of the scrollview but above it is contact 0 , contact 1. So I am very close please help thanks.
Also, the above is what happens when I add 5 items to the panel thatâs in the scroll view. the following happens when I add 20, how can I make it so that the items stay the same size and the panel and scroll view change size intead so I can use the scrollbar? thanks
Content size fitter on the content portion is the way to go for an expanding scroll view.
As for the elements, you can set their pivot/anchor to the top left if thatâs where you want them to startâŚI think thatâs what I usually do.
Try playing with some options on the vertical layout group so the size doesnât change like that, I think.
Image sv = GameObject.Find("Image").GetComponent<Image>();
ContentSizeFitter csf0 = sv.gameObject.AddComponent<ContentSizeFitter>();
Here is my attempt at setting the minHeight for the children of that Image. Donât know how else to set the height for the children of the Image.
//Assign all the children of the content panel to an array.
LayoutElement[] myLayoutElements = sv.gameObject.GetComponentsInChildren<LayoutElement>();
//For each child in the array change its LayoutElement's minimum height size to 64.
foreach (LayoutElement element in myLayoutElements)
{
element.minHeight = 64f;
}
I cant figure out how to set the pivot of the Image. The Image that I use to add all my children to has its rect Tranform set to top left. This doesnt stop the blue children from adding them selves not aligned.
Any tips thanks?
The VerticalLayoutGroup should have a property for child alignment, and should control the positioning and sizing of child elements entirely. It also has an option for whether the children should stretch to fit, although if you get your ContentSizeFitter working properly, they wonât have to change size to fit because there will always be enough room.
Hereâs a guide for a similar implementation that might help you along: Creating Dynamic Scrollable Lists with New Unity Canvas UI - folio3
When you click on that little positioning icon/image there in the RectTransform⌠read the information there. There are some key combination/shortcuts you can use for fast presets. Also, the pivot top left would be: x = 0, y = 1
Plus, @LiterallyJeff responded as I was writing, so try that stuff, too.
I am reading Creating Dynamic Scrollable Lists with New Unity Canvas UI - folio3
They use a listItem as a prefab, what kind of ui is a ListItem, I cant find it in my list of items to use.thanks
I skimmed that to see what you were talking about⌠and came to the conclusion that you either didnât read it, or you read & forgot⌠(and should read that section, again).
Itâs there, they explain itâŚ
Their âlist itemâ is comprised of a few pieces, and then made into a prefab for re-use in the code
Sorry about that. Misunderstood what it was you were doing.
Amazing guys. I finally figured it out, I see what you mean by doing most of the work in the editor. I have two pics of the results that I got, for a list of contacts that I dynamically populate. The only problem left is that the contact list starts at the half way point of the list. Say there is 100 contacts, the list will start at 50. I can scroll up and down it. How do I make that list create and start at 0? Here is pics