Skip to content

Instantly share code, notes, and snippets.

@thebeardphantom
Created April 13, 2015 23:52
Show Gist options
  • Save thebeardphantom/3cb8c2ea53c4828fdbad to your computer and use it in GitHub Desktop.
Save thebeardphantom/3cb8c2ea53c4828fdbad to your computer and use it in GitHub Desktop.
Basic UIList
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
namespace Rubycone.BoltAction {
[ExecuteInEditMode]
[RequireComponent(typeof(LayoutElement))]
public class InferSize : MonoBehaviour {
public Graphic targetGraphic;
public Vector2 minSizeOffset, preferredSizeOffset, flexibleSizeOffset;
LayoutElement layout;
protected override void OnAwake() {
layout = GetComponent<LayoutElement>();
if(GetComponent<Button>() != null) {
targetGraphic = GetComponentInChildren<Text>();
preferredSizeOffset.x = 30;
}
}
protected override void OnUpdate() {
if(targetGraphic != null) {
layout.minWidth = LayoutUtility.GetMinWidth(targetGraphic.rectTransform) + minSizeOffset.x;
layout.minHeight = LayoutUtility.GetMinHeight(targetGraphic.rectTransform) + minSizeOffset.y;
layout.preferredWidth = LayoutUtility.GetPreferredWidth(targetGraphic.rectTransform) + preferredSizeOffset.x;
layout.preferredHeight = LayoutUtility.GetPreferredHeight(targetGraphic.rectTransform) + preferredSizeOffset.y;
layout.flexibleWidth = LayoutUtility.GetFlexibleWidth(targetGraphic.rectTransform) + flexibleSizeOffset.x;
layout.flexibleHeight = LayoutUtility.GetFlexibleHeight(targetGraphic.rectTransform) + flexibleSizeOffset.y;
}
}
}
}
using UnityEngine;
using System.Collections;
using Rubycone.BoltAction;
using System.Collections.Generic;
using UnityEngine.UI;
namespace Rubycone.UI {
[ExecuteInEditMode]
[RequireComponent(typeof(VerticalLayoutGroup))]
public class UIList : MonoBehaviour {
[SerializeField, Header("Settings")]
int fontSize;
[SerializeField]
FontStyle fontStyle;
[SerializeField]
float top, left, right, bottom;
[SerializeField]
Color backgroundColor, alternateColor;
[SerializeField]
bool alternateColors;
[Header("Items")]
public List<string> elements = new List<string>();
List<ListItem> cells = new List<ListItem>();
protected override void OnUpdate() {
if(elements.Count != cells.Count) {
RefreshList();
}
for(int i = 0; i < elements.Count; i++) {
var li = cells[i];
li.text.text = elements[i];
li.text.fontSize = fontSize;
li.text.fontStyle = fontStyle;
li.background.color = (alternateColors && i % 2 != 0) ? alternateColor : backgroundColor;
li.rt.anchorMin = Vector2.zero;
li.rt.anchorMax = Vector2.one;
li.rt.offsetMax = new Vector2(right, top);
li.rt.offsetMin = new Vector2(left, bottom);
}
}
private void RefreshList() {
while(elements.Count > cells.Count) {
cells.Add(CreateListItem());
}
while(elements.Count < cells.Count) {
DestroyLastListItem();
}
}
private void DestroyLastListItem() {
var last = cells[cells.Count - 1];
cells.RemoveAt(cells.Count - 1);
if(Application.isPlaying) {
Destroy(last.gameObj);
}
else {
DestroyImmediate(last.gameObj);
}
}
private ListItem CreateListItem() {
var newChild = new GameObject("ListItem");
var newText = new GameObject("ListItemText");
//Set parents and scale
newText.transform.parent = newChild.transform;
newChild.transform.parent = transform;
ResetTransform(newText.transform);
ResetTransform(newChild.transform);
var textRect = newText.AddComponent<RectTransform>();
//Create necessary components
var background = newChild.AddComponent<Image>();
var text = newText.AddComponent<Text>();
var selectable = newText.AddComponent<Selectable>();
var inferrer = newChild.AddComponent<InferSize>();
selectable.targetGraphic = text;
inferrer.targetGraphic = text;
return new ListItem(newChild, text, textRect, background);
}
private void ResetTransform(Transform t) {
t.localPosition = Vector3.zero;
t.localRotation = Quaternion.identity;
t.localScale = Vector3.one;
}
public struct ListItem {
public GameObject gameObj;
public Text text;
public RectTransform rt;
public Image background;
public ListItem(GameObject gameObj, Text text, RectTransform rt, Image background) {
this.gameObj = gameObj;
this.text = text;
this.rt = rt;
this.background = background;
}
}
}
}
@thebeardphantom
Copy link
Author

Both files required in project. UIList creates the actual list, while InferSize basically is a LayoutElement that uses another component to resize this one. This was created for Buttons in Layout Groups, as the button's background would get used for sizing, which having a preferred size of 0 would cause the button to be smushed. Adding the InferSize script causes the Button's Image graphic to use the Text component underneath to configure its Preferred sizes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment