Hello All:
Often in our games we need scrollable lists to show scores, inventory items, in-app purchase UI etc. In this post I will show how to make a dynamic scrollable list to achieve earlier mentioned UI screens.
This post will be a part of Two post series.
By the end of tutorial, we will have our camera doing something similar to this.
This post will require understanding of following components
We will start by creating an empty screen.
Then create a panel in the scene.
Then Add "Mask" component to the panel (By clicking Add Component and searching for Mask).
Add ScrollRect with Horizontal checked and vertical unchecked (We are create a horizontal list).
Often in our games we need scrollable lists to show scores, inventory items, in-app purchase UI etc. In this post I will show how to make a dynamic scrollable list to achieve earlier mentioned UI screens.
This post will be a part of Two post series.
- Part 1 will show list generation using static data.
- Part 2 will show list generation using data fetched from a web service.
By the end of tutorial, we will have our camera doing something similar to this.
This post will require understanding of following components
- Mask: This component is used to mask the child game objects. More details can be found here.
- ScrollRect: This component is used to provide horizontal and vertical scrolling. More details can be found here.
We will start by creating an empty screen.
Then create a panel in the scene.
Panel |
Then Add "Mask" component to the panel (By clicking Add Component and searching for Mask).
Add ScrollRect with Horizontal checked and vertical unchecked (We are create a horizontal list).
Now add an empty GameObject to the panel and name it "Grid", this will serve as container for all the items of the grid. Assign this Grid to "Content"of ScrollRect component of the panel.
Grid with GridLayoutGroup and Content Size filter |
As we are creating a horizontal list so we will constraint on Row Count.
Now Add an Image to Grid, this will be template for the items which we will add on run time.
Now create a prefab out of the image we just added and rename it p_Item.
We can keep the original Item on the scene and disable it. In case in future we want to change our prefab we can use this for visualization.
Now we will be adding Two script component.
- One for list generation
- Second for the item to handle item specific actions
using UnityEngine; using System.Collections; using UnityEngine.UI; using System.Collections.Generic; public class DynamicScrollableGrid : MonoBehaviour { /// <summary> /// Scroll bar for the list /// </summary> public Scrollbar scrollBar; /// <summary> /// Item prefab /// </summary> public GameObject item; List<GameObject> items; /// <summary> /// Grid which contains the items /// </summary> public GridLayoutGroup grid; public ScrollRect scrollRect; public Text currentCount; // Use this for initialization Vector3 autoLocalScale; void Start() { items = new List<GameObject>(); autoLocalScale = new Vector3(1, 1, 1); RefreshList(); } public void RefreshList() { StartCoroutine(GenerateItems()); } public IEnumerator GenerateItems() { System.Random rand = new System.Random(); currentCount.text = "Current Count: " + 0.ToString(); ///Clearing old list items.ForEach((go) => GameObject.Destroy(go)); items.Clear(); int randomItemCount = rand.Next(20, 100); for (int index = 0; index < randomItemCount; index++) { GameObject localItem = (GameObject)Instantiate(item, Vector3.zero, Quaternion.identity); ///Setting parent for the item localItem.transform.SetParent(grid.transform); localItem.GetComponent<Item>().Id = index + 1; ///Important as instatiated item can have random scale and might not be visible localItem.transform.localScale = autoLocalScale; localItem.transform.localPosition = Vector3.zero; items.Add(localItem); } yield return new WaitForSeconds(.1f); ///1. Two ways to move the scroll to first item scrollRect.horizontalNormalizedPosition = 0; currentCount.text = "Current Count: " + randomItemCount.ToString(); //2. Moving the scroll bar to left //scrollBar.value = 0; } }
Create another C# script: Item and add following code.
using UnityEngine; using System.Collections; using UnityEngine.UI; public class Item : MonoBehaviour { public int Id; public void Start() { foreach (Transform localTransform in transform) { if (localTransform.name == "Id") { localTransform.GetComponent<Text>().text = (Id).ToString(); } } } public void OnClick() { GameObject.Find("ButtonClicked").GetComponent<Text>().text = "Item #" + Id.ToString() + " Clicked"; Debug.Log("Item #" + Id.ToString() + " Clicked"); } }
Now Attach DynamicScrollableGrid to the Canvas and assign the public variables
We are passing scrollbar to the script as we can set the starting position of the list by changing the scrollbar value.
Add Item to p_Item and add event handler for onClick
Now save the scene and run it. You will see a list as shown below
Hope this helps. The full working code can be found here.
Thanks for printing this post. Hope you liked it.
Keep visiting and sharing.
Thanks,
Ashwani.
Keep visiting and sharing.
Thanks,
Ashwani.
Could be clearer if the scrollBar and the Refresh button addittion shown .
ReplyDelete