Advertisement
Guest User

Untitled

a guest
May 28th, 2017
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.60 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class Zaicheg : MonoBehaviour
  6. {
  7.     public GUISkin mys; // скин
  8.     public float bHeight = 30f; // высота кнопок дефолтная
  9.     public float bWidth = 100f; // ширина кнопок дефолтная
  10.     int level = 0; // текущий уровень
  11.     Item selected; // выбранная нами кнопка
  12.     List<Item> list = new List<Item>(); // список элементов
  13.     public Item itemTop; // объект служит родителем для элементов верхнего уровня
  14.     int levelsCount = 0; // количество уровней иерархии
  15.  
  16.     public TextAsset txtStruct; // текстовый файл, в котором описана структура
  17.  
  18.     // элементы списка
  19.     public class Item
  20.     {
  21.         public bool drop = true; // выпадает ли из неё меню
  22.         public string name; // название
  23.         public Item parent; // элемент-родитель
  24.         public Item root; // корневой элемент
  25.         public List<Item> childs = new List<Item>();
  26.         public int level; // уровень в иерархии
  27.         public int side; // 0 - сверху/снизу, 1 - слева/справа
  28.         public int sideChilds; // 0 - сверху/снизу, 1 - слева/справа
  29.         public int number; // порядковый номер на этом уровне у этого родителя
  30.         public bool show; // отображать ли пункт
  31.         public Rect bRect; // ректангл элемента
  32.         Item itemTop; // храним информацию о "самом-самом верхнем элементе"
  33.  
  34.         // так, для порядку. Не используйте
  35.         public Item()
  36.         {
  37.  
  38.         }
  39.  
  40.         // основной конструктор. Пустой не используйте
  41.         public Item(int _level, string _name, bool _drop, Item _itemTop)
  42.         {
  43.             level = _level;
  44.             name = _name;
  45.             drop = _drop;
  46.             number = 0;
  47.             show = false;
  48.             parent = _itemTop;
  49.             root = _itemTop;
  50.             itemTop = _itemTop;
  51.         }
  52.  
  53.         // устанавливаем положение элемента относительно других, исходя из его уровня
  54.         public void SetSide()
  55.         {
  56.             if (level == 0)
  57.             {
  58.                 side = 1;
  59.                 sideChilds = 0;
  60.             }
  61.             if (level > 0)
  62.             {
  63.                 side = 0;
  64.                 sideChilds = 1;
  65.             }
  66.         }
  67.  
  68.         // вычисляем корневой объект иерархии для этого элемента
  69.         public void CalcRoot()
  70.         {
  71.             Item lt = parent;
  72.             while (lt.parent != null && lt.parent != itemTop)
  73.             {
  74.                 lt = lt.parent;
  75.                 root = lt;
  76.             }
  77.  
  78.             if (lt.parent == itemTop)
  79.             {
  80.                 root = lt;
  81.             }
  82.         }
  83.     }
  84.  
  85.     void Start()
  86.     {
  87.         // инициализируем, чтобы ошибок не было до момента определения
  88.         selected = new Item(0, "", false, itemTop);
  89.         itemTop = new Item(0, "itemTop", false, itemTop);
  90.  
  91.         ReadTXT(); // читаем файл и вытаскиваем из него нужную информацию
  92.         Output(); // выводим отчёт о создании элементов
  93.     }
  94.  
  95.     // парсинг файла и составление листа
  96.     void ReadTXT()
  97.     {
  98.         string[] lines = txtStruct.text.Split('\n'); // разбиваем на строки
  99.  
  100.         string name = ""; // имя текущего элемента
  101.         int level = 0; // уровень текущего элемента
  102.         int prelevel = 0; // уровень предыдущего элемента
  103.  
  104.         // перебираем элементы
  105.         for (int i = 0; i < lines.Length; i++)
  106.         {
  107.             level = lines[i].IndexOf('>'); // уровень определяется кол-вом пробелов перед тегом
  108.             name = lines[i].Substring(level + 1); // имя — всё что после тега
  109.             name = name.Trim(); // обрезаем пробелы по краям имени
  110.             name = name.Trim('\n');
  111.  
  112.             list.Add(new Item(level, name, false, itemTop)); // создаём элемент
  113.            
  114.             // определяем его родителя
  115.             if (level > 0)
  116.             {
  117.                 // если его уровень больше чем у предшественника, то предшественник — родитель
  118.                 // если уровни равны, то у них общий родитель
  119.                 // если уровень меньше, то ищем предыдущий элемент с таким уровнем — с ним общий родитель
  120.                 if (level > prelevel)
  121.                     GetLast(0).parent = GetLast(1);
  122.                 else if (level == prelevel)
  123.                     GetLast(0).parent = GetLast(1).parent;
  124.                 else if (level < prelevel)
  125.                     for (int j = 0; j < list.Count; j++)
  126.                         if (list[j].level == level)
  127.                             GetLast(0).parent = list[j].parent;
  128.  
  129.                 GetLast(0).parent.drop = true; // раз у элемента есть дети, то он выпадающий
  130.                 GetLast(0).parent.childs.Add(GetLast(0)); // записываем в родителя информацию о его детях
  131.             }
  132.             else
  133.             {
  134.                 GetLast(0).parent = itemTop; // если уровень верхний, то родитель - нулл
  135.                 itemTop.childs.Add(GetLast(0));
  136.             }
  137.  
  138.             prelevel = level;
  139.  
  140.             if (level > levelsCount)
  141.                 levelsCount = level; // считаем количество уровней
  142.         }
  143.  
  144.         int numNull = 0;
  145.         for (int i = 0; i < list.Count; i++)
  146.         {
  147.             list[i].SetSide(); // определяем стороны выпадания списков исходя из уровня
  148.             list[i].CalcRoot(); // выявляем корни для всех элементов
  149.  
  150.             // определяем порядок внутри уровней и внутри родителей
  151.             int num = 0;
  152.             for (int j = 0; j < list.Count; j++)
  153.             {
  154.                 if (list[j].parent == list[i])
  155.                 {
  156.                     list[j].number = num;
  157.                     num++;
  158.                 }
  159.             }
  160.  
  161.             // определяем порядок для верхнего уровня
  162.             if (list[i].parent == itemTop)
  163.             {
  164.                 list[i].number = numNull;
  165.                 numNull++;
  166.             }
  167.         }
  168.         selected = itemTop;
  169.     }
  170.  
  171.     // выводим список в консоль
  172.     void Output()
  173.     {
  174.         Debug.Log("======== Output ========");
  175.         for (int i = 0; i < list.Count; i++)
  176.         {
  177.             Debug.Log("Имя: " + list[i].name);
  178.             Debug.Log("Уровень: " + list[i].level);
  179.             Debug.Log("Родитель: " + list[i].parent.name);
  180.             Debug.Log("Корень: " + list[i].root.name);
  181.             Debug.Log("Номер: " + list[i].number);
  182.  
  183.         }
  184.     }
  185.  
  186.     void OnGUI()
  187.     {
  188.         GUI.skin = mys; // применяем скин
  189.  
  190.         CalcRectangles(); // считаем, какие элементы отображать и где их располагать
  191.  
  192.         // рисуем кнопки
  193.         for (int i = 0; i < list.Count; i++)
  194.             if (list[i].show)
  195.                 if (GUI.Button(list[i].bRect, list[i].name))
  196.                     selected = list[i];
  197.     }
  198.  
  199.     // считаем, какие элементы отображать и где их располагать
  200.     void CalcRectangles()
  201.     {
  202.         // по умолчанию ничего не отображается
  203.         for (int i = 0; i < list.Count; i++)
  204.             list[i].show = false;
  205.  
  206.         // устанавливаем элементы, которые должны отображаться
  207.         // 1 — выбранный элемент
  208.         // 2 — дети выбранного элемента
  209.         // 3 — элементы, у которых общий родитель с выбранным элементом
  210.         // 4 — элементы, которые по уровню ниже выбранного и имеют с ним общий корень
  211.         for (int i = 0; i < list.Count; i++)
  212.         {
  213.             if (list[i].level == 0)
  214.                 list[i].show = true;
  215.  
  216.             if (list[i] == selected)
  217.                 list[i].show = true;
  218.  
  219.             if (list[i].parent == selected)
  220.                 list[i].show = true;
  221.  
  222.             if (list[i].parent == selected.parent)
  223.                 list[i].show = true;
  224.  
  225.             if (list[i].level < selected.level && list[i].root == selected.root)
  226.                 list[i].show = true;
  227.         }
  228.  
  229.         // считаем ректанглы. Надо компактнее сделать
  230.         for (int i = 0; i < list.Count; i++)
  231.         {
  232.             float left = 0f;
  233.             float top = 0f;
  234.             if (list[i].side == 1)
  235.             {
  236.                 left = bWidth * list[i].number;
  237.                 top = 0;
  238.             }
  239.             if (list[i].side == 0)
  240.             {
  241.                 if (list[i].parent.sideChilds == 0)
  242.                 {
  243.                     left = list[i].parent.bRect.xMin;
  244.                     top = list[i].parent.bRect.yMax + bHeight * list[i].number;
  245.                 }
  246.                 if (list[i].parent.sideChilds == 1)
  247.                 {
  248.                     left = list[i].parent.bRect.xMax;
  249.                     top = list[i].parent.bRect.yMin + bHeight * list[i].number;
  250.                 }
  251.             }
  252.  
  253.             list[i].bRect = new Rect(left, top, bWidth, bHeight);
  254.         }
  255.     }
  256.  
  257.     // получаем последний элемент списка (или определённый с конца)
  258.     Item GetLast(int i)
  259.     {
  260.         return list[list.Count - i - 1];
  261.     }
  262. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement