Advertisement
Guest User

Untitled

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