Advertisement
Guest User

Untitled

a guest
May 28th, 2017
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.46 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.     float bHeight = 50f; // высота кнопок
  9.     float bWidth = 200f; // ширина кнопок
  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.         public void CalcRect(float _bWidth, float _bHeight)
  86.         {
  87.             ;
  88.         }
  89.     }
  90.  
  91.     void Start()
  92.     {
  93.         // инициализируем, чтобы ошибок не было до момента определения
  94.         selected = new Item(0, "", false, itemTop);
  95.         itemTop = new Item(0, "itemTop", false, itemTop);
  96.  
  97.         ReadTXT(); // читаем файл и вытаскиваем из него нужную информацию
  98.         Output(); // выводим отчёт о создании элементов
  99.     }
  100.  
  101.     // парсинг файла и составление листа
  102.     void ReadTXT()
  103.     {
  104.         string[] lines = txtStruct.text.Split('\n'); // разбиваем на строки
  105.  
  106.         string name = ""; // имя текущего элемента
  107.         int level = 0; // уровень текущего элемента
  108.         int prelevel = 0; // уровень предыдущего элемента
  109.  
  110.         // перебираем элементы
  111.         for (int i = 0; i < lines.Length; i++)
  112.         {
  113.             level = lines[i].IndexOf('>'); // уровень определяется кол-вом пробелов перед тегом
  114.             name = lines[i].Substring(level); // имя — всё что после тега
  115.             name = name.Trim();
  116.             name = name.Trim('\n');
  117.  
  118.             list.Add(new Item(level, name, false, itemTop)); // создаём элемент
  119.            
  120.             // определяем его родителя
  121.             if (level > 0)
  122.             {
  123.                 // если его уровень больше чем у предшественника, то предшественник — родитель
  124.                 // если уровни равны, то у них общий родитель
  125.                 // если уровень меньше, то ищем предыдущий элемент с таким уровнем — с ним общий родитель
  126.                 if (level > prelevel)
  127.                     GetLast(0).parent = GetLast(1);
  128.                 else if (level == prelevel)
  129.                     GetLast(0).parent = GetLast(1).parent;
  130.                 else if (level < prelevel)
  131.                     for (int j = 0; j < list.Count; j++)
  132.                         if (list[j].level == level)
  133.                             GetLast(0).parent = list[j].parent;
  134.  
  135.                 GetLast(0).parent.drop = true; // раз у элемента есть дети, то он выпадающий
  136.                 GetLast(0).parent.childs.Add(GetLast(0)); // записываем в родителя информацию о его детях
  137.             }
  138.             else
  139.             {
  140.                 GetLast(0).parent = itemTop; // если уровень верхний, то родитель - нулл
  141.                 itemTop.childs.Add(GetLast(0));
  142.             }
  143.  
  144.             prelevel = level;
  145.  
  146.             if (level > levelsCount)
  147.                 levelsCount = level; // считаем количество уровней
  148.         }
  149.  
  150.         int numNull = 0;
  151.         for (int i = 0; i < list.Count; i++)
  152.         {
  153.             list[i].SetSide(); // определяем стороны выпадания списков исходя из уровня
  154.             list[i].CalcRoot();
  155.  
  156.             // определяем порядок внутри уровней и внутри родителей
  157.             int num = 0;
  158.             for (int j = 0; j < list.Count; j++)
  159.             {
  160.                 if (list[j].parent == list[i])
  161.                 {
  162.                     list[j].number = num;
  163.                     num++;
  164.                 }
  165.             }
  166.  
  167.             // определяем порядок для верхнего уровня
  168.             if (list[i].parent == itemTop)
  169.             {
  170.                 list[i].number = numNull;
  171.                 numNull++;
  172.             }
  173.         }
  174.         selected = itemTop;
  175.     }
  176.  
  177.     // выводим список в консоль
  178.     void Output()
  179.     {
  180.         Debug.Log("======== Output ========");
  181.         for (int i = 0; i < list.Count; i++)
  182.         {
  183.             Debug.Log("Имя: " + list[i].name);
  184.             Debug.Log("Уровень: " + list[i].level);
  185.             Debug.Log("Родитель: " + list[i].parent.name);
  186.             Debug.Log("Корень: " + list[i].root.name);
  187.             Debug.Log("Номер: " + list[i].number);
  188.  
  189.         }
  190.     }
  191.  
  192.     void OnGUI()
  193.     {
  194.         GUI.skin = mys; // применяем скин
  195.  
  196.         // по умолчанию ничего не отображается
  197.         for (int i = 0; i < list.Count; i++)
  198.             list[i].show = false;
  199.        
  200.         // устанавливаем элементы, которые должны отображаться
  201.         // 1 — выбранный элемент
  202.         // 2 — дети выбранного элемента
  203.         // 3 — элементы, у которых общий родитель с выбранным элементом
  204.         // 4 — элементы, которые по уровню ниже выбранного и имеют с ним общий корень
  205.         for (int i = 0; i < list.Count; i++)
  206.         {
  207.             if (list[i] == selected)
  208.                 list[i].show = true;
  209.  
  210.             if (list[i].parent == selected)
  211.                 list[i].show = true;
  212.            
  213.             if (list[i].parent == selected.parent)
  214.                 list[i].show = true;
  215.  
  216.             if (list[i].level < selected.level && list[i].root == selected.root)
  217.                 list[i].show = true;
  218.         }
  219.  
  220.         // считаем ректанглы. Надо компактнее сделать
  221.         for (int i = 0; i < list.Count; i++)
  222.         {
  223.             if (list[i].show)
  224.             {
  225.                 float left = 0f;
  226.                 float top = 0f;
  227.                 if (list[i].side == 1)
  228.                 {
  229.                     left = bWidth * list[i].number;
  230.                     top = 0;
  231.                 }
  232.                 if (list[i].side == 0)
  233.                 {
  234.                     if (list[i].parent.sideChilds == 0)
  235.                     {
  236.                         left = list[i].parent.bRect.xMin;
  237.                         top = list[i].parent.bRect.yMax + bHeight * list[i].number;
  238.                     }
  239.                     if (list[i].parent.sideChilds == 1)
  240.                     {
  241.                         left = list[i].parent.bRect.xMax;
  242.                         top = list[i].parent.bRect.yMin + bHeight * list[i].number;
  243.                     }
  244.                 }
  245.  
  246.                 list[i].bRect = new Rect(left, top, bWidth, bHeight);
  247.             }
  248.         }
  249.  
  250.         // рисуем кнопки
  251.         for (int i = 0; i < list.Count; i++)
  252.         {
  253.             if (GUI.Button(list[i].bRect, list[i].name))
  254.             {
  255.                 selected = list[i];
  256.             }
  257.         }
  258.     }
  259.  
  260.     // получаем последний элемент списка (или определённый с конца)
  261.     Item GetLast(int i)
  262.     {
  263.         return list[list.Count - i - 1];
  264.     }
  265. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement