Skip to content

Instantly share code, notes, and snippets.

@kyubuns
Last active December 26, 2018 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kyubuns/2d114953bc3afa4d384bf0e8f2728879 to your computer and use it in GitHub Desktop.
Save kyubuns/2d114953bc3afa4d384bf0e8f2728879 to your computer and use it in GitHub Desktop.
// HorizontalLayoutGroupのめっちゃシンプルで挙動が分かりやすくてスクリプトからサクッと入れれる版。
// SourceというGameObjectを、itemsの数だけ左から右に並べる。
var source = ui.Get<RectTransform>("Source");
var listView = new ListView(new LeftToRightLayouter(), source);
using (var editor = listView.Edit())
{
foreach(var item in items)
{
var element = editor.Create();
element.Get<Text>("Name").text = item.Name;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Baum2;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Baum2.Util
{
public class ListView
{
private readonly IListViewLayouter Layouter;
private readonly RectTransform Source;
private readonly Transform Parent;
public ListView(IListViewLayouter layouter, RectTransform source)
{
Layouter = layouter;
Source = source;
Parent = source.transform.parent;
Source.gameObject.SetActive(false);
if (source.GetComponent<UIRoot>() == null) UIRoot.SetupCache(source.gameObject);
}
public static EditMode CreateDisposable(IListViewLayouter layouter, RectTransform source)
{
var listView = new ListView(layouter, source);
return listView.Edit();
}
public EditMode Edit()
{
return new EditMode(this);
}
private void Clear()
{
for (var i = 0; i < Parent.childCount; ++i)
{
var child = Parent.GetChild(i);
if (child.name == "Created")
{
Object.Destroy(child.gameObject);
}
}
}
private UIRoot Create()
{
var newObject = Object.Instantiate(Source, Parent, true);
newObject.transform.localPosition = Source.transform.localPosition;
newObject.transform.localRotation = Quaternion.identity;
newObject.transform.localScale = Vector3.one;
newObject.gameObject.name = "Created";
newObject.gameObject.SetActive(true);
return UIRoot.UpdateCache(newObject.gameObject);
}
private void Layout(List<RectTransform> items)
{
if (items.Count == 0) return;
Layouter.Layout(items.ToArray());
}
public class EditMode : IDisposable
{
private readonly ListView ListView;
private readonly List<RectTransform> Items = new List<RectTransform>();
public EditMode(ListView listView)
{
ListView = listView;
ListView.Clear();
}
public UIRoot Create()
{
var item = ListView.Create();
Items.Add(item.GetComponent<RectTransform>());
return item;
}
public void Dispose()
{
ListView.Layout(Items);
}
}
}
public interface IListViewLayouter
{
void Layout(RectTransform[] items);
}
public class AreaLayouter : IListViewLayouter
{
private readonly RectTransform Area;
public AreaLayouter(RectTransform area)
{
Area = area;
Area.gameObject.SetActive(false);
}
public void Layout(RectTransform[] items)
{
Layout(Area.rect, items, Area.anchoredPosition.y, items.Length);
}
public static void Layout(Rect area, RectTransform[] items, float y, int column)
{
var startX = area.xMin;
var endX = area.xMax;
var d = (endX - startX) / (column + 1);
var startDiff = ((endX - startX) - d * (items.Length + 1)) / 2f;
for (var i = 0; i < items.Length; ++i)
{
items[i].anchoredPosition = new Vector2(startX + startDiff + d * (i + 1), y);
}
}
}
public class MultiRowAreaLayouter : IListViewLayouter
{
private readonly RectTransform Area;
private readonly int Column;
public MultiRowAreaLayouter(RectTransform area, int column)
{
Area = area;
Column = column;
Area.gameObject.SetActive(false);
}
public void Layout(RectTransform[] items)
{
var chunks = items.Select((v, i) => new {v, i})
.GroupBy(x => x.i / Column)
.Select(g => g.Select(x => x.v));
var size = items[0].rect;
var startY = Area.anchoredPosition.y + Area.rect.yMax - size.height / 2;
foreach (var chunk in chunks)
{
AreaLayouter.Layout(Area.rect, chunk.ToArray(), startY, Column);
startY -= size.height;
}
}
}
public class LeftToRightLayouter : IListViewLayouter
{
public void Layout(RectTransform[] items)
{
var x = items[0].anchoredPosition.x;
var y = items[0].anchoredPosition.y;
var w = items[0].rect.width;
foreach (var item in items)
{
item.anchoredPosition = new Vector2(x, y);
x += w;
}
}
}
public class LeftToRightLayouterByCenter : IListViewLayouter
{
public void Layout(RectTransform[] items)
{
var y = items[0].anchoredPosition.y;
var w = items[0].rect.width;
var totalWidth = w * (items.Length - 1);
var x = items[0].anchoredPosition.x - totalWidth / 2f;
foreach (var item in items)
{
item.anchoredPosition = new Vector2(x, y);
x += w;
}
}
}
public class TopToBottomLayouter : IListViewLayouter
{
public void Layout(RectTransform[] items)
{
var x = items[0].anchoredPosition.x;
var y = items[0].anchoredPosition.y;
var h = items[0].rect.height;
foreach (var item in items)
{
item.anchoredPosition = new Vector2(x, y);
y -= h;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment