unity四叉树

  1 public class QuadTree_1
  2 {
  3     //节点内允许的最大对象
  4     private int maxObjs = 1;
  5 
  6     //最大层级
  7     private int maxLvl = 3;
  8 
  9     //当前层级
 10     private int lvl;
 11 
 12     //当前层级内的对象
 13     private List<Transform> transList;
 14 
 15     //rect范围
 16     private Vector3 minPos;
 17 
 18     private Vector3 maxPos;
 19 
 20     private Vector2 dis;
 21     //子节点
 22     private List<QuadTree_1> childs;
 23 
 24     private QuadTree_1 parent;
 25     
 26     private List<Color> color = new List<Color>() {Color.cyan, Color.blue, Color.green, Color.red, Color.yellow, Color.gray};
 27     
 28     public QuadTree_1(Vector3 minPos, Vector3 maxPos, QuadTree_1 parent, int lvl, int maxObjs, int maxLvl)
 29     {
 30         this.minPos = minPos;
 31         this.maxPos = maxPos;
 32         dis = new Vector2(maxPos.x - minPos.x, maxPos.z - minPos.z);
 33         this.parent = parent;
 34         this.lvl = lvl;
 35         this.maxObjs = maxObjs;
 36         this.maxLvl = maxLvl;
 37         transList = new List<Transform>();
 38         childs = new List<QuadTree_1>(4);
 39     }
 40 
 41     public void Insert(Transform trans)
 42     {
 43         //直接往下找 递归下去
 44         if (childs.Count != 0 && lvl < maxLvl)
 45         {
 46             for (int j = 0; j < childs.Count; j++)
 47             {
 48                 if (childs[j].CheckArea(trans.position))
 49                 {
 50                     childs[j].Insert(trans);
 51                     return;
 52                 }
 53             }
 54             //处理临界状态
 55             transList.Add(trans);
 56             return;
 57         }
 58 
 59         transList.Add(trans);
 60         // Debug.Log($"当前等级{lvl}   最大等级{maxLvl}");
 61         if (transList.Count > maxObjs && lvl < maxLvl)
 62         {
 63             if (childs.Count == 0)
 64             {
 65                 Vector3 midPos = (maxPos + minPos) / 2;
 66                 Vector3 disL = new Vector3(dis.x / 2, 0, 0);
 67                 childs.Add(new QuadTree_1(midPos, maxPos, this, lvl + 1, maxObjs, maxLvl));
 68                 childs.Add(new QuadTree_1(midPos - disL, maxPos - disL, this, lvl + 1, maxObjs, maxLvl));
 69                 childs.Add(new QuadTree_1(minPos, midPos, this, lvl + 1, maxObjs, maxLvl));
 70                 childs.Add(new QuadTree_1(minPos + disL, midPos + disL, this, lvl + 1, maxObjs, maxLvl));
 71             }
 72             
 73             for (int i = transList.Count - 1; i >= 0; i--)
 74             {
 75                 for (int j = 0; j < childs.Count; j++)
 76                 {
 77                     if (childs[j].CheckArea(transList[i].position))
 78                     {
 79                         childs[j].Insert(transList[i]);
 80                         transList.Remove(transList[i]);
 81                         break;
 82                     }
 83                 }
 84             }
 85         }
 86     }
 87 
 88     public List<Transform> FindRoundPoint()
 89     {
 90         List<Transform> list = new List<Transform>();
 91         if (parent == null)
 92         {
 93             FindRoundPoint(ref list); 
 94         }
 95         else
 96         {
 97             parent.FindRoundPoint(ref list); 
 98         }
 99         
100         return list;
101     }
102 
103 
104     private void FindRoundPoint(ref List<Transform> list)
105     {
106         for (int i = 0; i < transList.Count; i++)
107         {
108             list.Add(transList[i]);
109         }
110 
111         for (int i = 0; i < childs.Count; i++)
112         {
113             childs[i].FindRoundPoint(ref list);
114         }
115     }
116     
117 
118     //根据区域进行递归查找会更快一些
119     public QuadTree_1 FindQuadTree(Transform target)
120     {
121         if (transList.Contains(target))
122         {
123             return this;
124         }
125 
126         for (int i = 0; i < childs.Count; i++)
127         {
128             if (childs[i].CheckArea(target.position))
129             {
130                 return childs[i].FindQuadTree(target);
131             }
132         }
133 
134         return null;
135     }
136 
137     private bool CheckArea(Vector3 pos)
138     {
139         return pos.x > minPos.x && pos.z > minPos.z && pos.x < maxPos.x && pos.z < maxPos.z;
140     }
141 
142     public void Clear()
143     {
144         transList.Clear();
145         parent = null;
146         for (int i = 0; i < childs.Count; i++)
147         {
148             childs[i].Clear();
149         }
150         childs.Clear();
151     }
152 
153     public void Draw()
154     {
155         Vector3 rb = minPos + new Vector3(dis.x, 0, 0);
156         Vector3 lt = maxPos - new Vector3(dis.x, 0, 0);
157         Debug.DrawLine(minPos, rb, color[lvl]);
158         Debug.DrawLine(rb, maxPos, color[lvl]);
159         Debug.DrawLine(maxPos, lt, color[lvl]);
160         Debug.DrawLine(lt, minPos, color[lvl]);
161         // for (int i = 0; i < transList.Count; i++)
162         // {
163         //     transList[i].GetComponent<MeshRenderer>().material.color = color[lvl];
164         // }
165         for (int i = 0; i < childs.Count; i++)
166         {
167             childs[i].Draw();
168         }
169     }
170 }

 

posted @ 2024-11-25 15:11  zjp971014  阅读(40)  评论(0)    收藏  举报