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 }