private void DrawColliders(QuadtreeNode quadtreeNode) { foreach (QuadtreeCollider collider in GetColliders(quadtreeNode)) { DrawCollider(collider); } }
private void DrawChildrenNode(QuadtreeNode quadtreeNode) { foreach (QuadtreeNode child in GetChildren(quadtreeNode)) { DrawQuadtreeNodes(child); } }
/// <summary> /// 绘制节点 /// </summary> /// <param name="node"></param> private void DrawNode(QuadtreeNode node) { Gizmos.color = GetNodeColor(node); // 绘制节点信息 DrawNodeInfomationText(node); }
/// <summary> /// 判断一个四叉树节点是否有子节点 /// </summary> /// <param name="quadtreeNode"></param> /// <returns></returns> private bool HaveChildren(QuadtreeNode quadtreeNode) { MethodInfo method = typeof(QuadtreeNode).GetMethod("HaveChildren", BindingFlags.Instance | BindingFlags.NonPublic); //Debug.Log("检测节点 " + quadtreeNode + " 有没有子节点:" + (bool)method.Invoke(quadtreeNode, null)); return((bool)method.Invoke(quadtreeNode, null)); }
private void DrawTipNode(QuadtreeNode quadtreeNode) { Gizmos.color = GetNodeColor(quadtreeNode); Handles.color = GetNodeColor(quadtreeNode); DrawArea(quadtreeNode); DrawColliders(quadtreeNode); }
private string GetNodeInfomationText(QuadtreeNode node) { string infomation = ""; infomation += "总碰撞器数:" + GetColliders(node).Count + "\n"; infomation += "最大检测半径:" + GetMaxRadius(node) + "\n"; return(infomation); }
private Color GetNodeColor(QuadtreeNode quadtreeNode) { Rect rootArea = GetArea(GetQuadtreeRoot()); Rect area = GetArea(quadtreeNode); float xLerp = Mathf.InverseLerp(rootArea.xMin, rootArea.xMax, area.x); float yLerp = Mathf.InverseLerp(rootArea.yMin, rootArea.yMax, area.y); return(new Color(xLerp, yLerp, 0.5f)); }
/// <summary> /// 绘制末端节点 /// </summary> /// <param name="quadtreeNode"></param> private void DrawTipNode(QuadtreeNode quadtreeNode) { // 根据节点设置颜色 Gizmos.color = GetNodeColor(quadtreeNode); Handles.color = GetNodeColor(quadtreeNode); // 绘制节点区域 DrawArea(quadtreeNode); // 绘制节点中的碰撞器 DrawColliders(quadtreeNode); }
private void DrawQuadtreeNodes(QuadtreeNode quadtreeNode) { if (HaveChildren(quadtreeNode)) { DrawChildrenNode(quadtreeNode); } else { DrawTipNode(quadtreeNode); } DrawNode(quadtreeNode); }
/// <summary> /// 根据节点位置获取节点颜色 /// </summary> /// <param name="quadtreeNode"></param> /// <returns></returns> private Color GetNodeColor(QuadtreeNode quadtreeNode) { // 获取根节点范围和要获取颜色的节点的范围,后续根据这两个范围确认颜色 Rect rootArea = GetArea(GetQuadtreeRoot()); Rect area = GetArea(quadtreeNode); // 计算要获取颜色的节点的位置在根节点范围中的比例 float xLerp = Mathf.InverseLerp(rootArea.xMin, rootArea.xMax, area.x); float yLerp = Mathf.InverseLerp(rootArea.yMin, rootArea.yMax, area.y); // 通过位置比例返回颜色,越靠右越红,越靠上越绿 return(new Color(xLerp, yLerp, 0.5f)); }
/// <summary> /// 绘制四叉树指定节点 /// </summary> /// <param name="quadtreeNode"></param> private void DrawQuadtreeNodes(QuadtreeNode quadtreeNode) { if (HaveChildren(quadtreeNode)) { // 有子节点的情况下,绘制子节点 DrawChildrenNode(quadtreeNode); } else { // 没有子节点,绘制末端节点 DrawTipNode(quadtreeNode); } // 绘制节点 DrawNode(quadtreeNode); }
private void DrawArea(QuadtreeNode quadtreeNode) { //Debug.Log("绘制区域为 " + GetArea(quadtreeNode) + " 的节点的区域"); Rect area = GetArea(quadtreeNode); Vector3 topRight = new Vector3(area.xMax, area.yMax, 0); Vector3 bottomRight = new Vector3(area.xMax, area.y, 0); Vector3 bottomLeft = new Vector3(area.x, area.y, 0); Vector3 topLeft = new Vector3(area.x, area.yMax, 0); Gizmos.DrawLine(topLeft, topRight); Gizmos.DrawLine(topRight, bottomRight); Gizmos.DrawLine(bottomRight, bottomLeft); Gizmos.DrawLine(bottomLeft, topLeft); }
/// <summary> /// 从当前节点开始,向上合并节点,直到不能合并为止 /// </summary> /// <returns></returns> private OperationResult UpwordMerge() { // 先准备一个合并失败的结果 OperationResult result = new OperationResult(false); // 从当前节点开始 QuadtreeNode currentNode = this; // 逻辑比较繁琐,使用死循环加跳出 while (true) { // 当前节点是 null,这种情况是合并完了根节点后的循环,直接结束循环 if (currentNode == null) { break; } // 当前节点是末梢,末梢本身不能合并,向上一级 if (!currentNode.HaveChildren()) { // 向上一级 currentNode = currentNode.parent; // 再次循环 continue; } // 当前节点不能合并,结束合并 if (!currentNode.NeedMerge()) { break; } // 合并并记录结果 result = currentNode.Merge(); // 向上移一级 currentNode = currentNode.parent; } return(result); }
/// <summary> /// 获取最大半径 /// </summary> /// <param name="quadtreeNode"></param> /// <returns></returns> private float GetMaxRadius(QuadtreeNode quadtreeNode) { return((float)typeof(QuadtreeNode).GetField("maxRadius", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(quadtreeNode)); }
/// <summary> /// 绘制节点信息 /// </summary> /// <param name="node"></param> private void DrawNodeInfomationText(QuadtreeNode node) { Handles.Label(GetArea(node).center, GetNodeInfomationText(node)); }
private void Awake() { _root = new QuadtreeNode(QuadtreeConfig.startArea); // 节点创建过程中使用了Resources.Load,这个方法不能通过类的字段声明时赋值来调用 }
/// <summary> /// 获取一个节点及其所有子节点的碰撞器总数 /// </summary> /// <param name="quadtreeNode"></param> /// <returns></returns> private int GetCollidersNumber(QuadtreeNode quadtreeNode) { return((int)typeof(QuadtreeNode).GetMethod("GetColliderNumbers", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(quadtreeNode, new object[0])); }
/// <summary> /// 获取一个节点的所有碰撞器 /// </summary> /// <param name="quadtreeNode"></param> /// <returns></returns> private List <QuadtreeCollider> GetColliders(QuadtreeNode quadtreeNode) { return((List <QuadtreeCollider>) typeof(QuadtreeNode).GetField("colliders", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(quadtreeNode)); }
/// <summary> /// 获取指定节点的区域 /// </summary> /// <param name="quadtreeNode"></param> /// <returns></returns> private Rect GetArea(QuadtreeNode quadtreeNode) { return((Rect)typeof(QuadtreeNode).GetField("area", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(quadtreeNode)); }
/// <summary> /// 获取一个四叉树节点的所有子节点 /// </summary> /// <param name="quadtreeNode"></param> /// <returns></returns> private IEnumerable <QuadtreeNode> GetChildren(QuadtreeNode quadtreeNode) { return((List <QuadtreeNode>) typeof(QuadtreeNode).GetField("children", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(quadtreeNode)); }
/// <summary> /// 根节点之外的节点的构造方法 /// </summary> /// <param name="area"></param> /// <param name="parent"></param> internal QuadtreeNode(Rect area, QuadtreeNode parent) : this(area) { this.parent = parent; }