/// <summary> /// 布局标记组 /// </summary> /// <param name="entitys">标记组</param> private void LayoutEntityGroup(EntityList entitys) { Entity first = entitys[0]; Entity last = entitys[entitys.Count - 1]; int centerIndex = Mathf.FloorToInt(entitys.Count / 2.0f); int leftIndex = centerIndex + (entitys.Count % 2); int rightIndex = centerIndex - 1; float centerAngle = first.Angle + (last.Angle - first.Angle) / 2; float leftAngle = centerAngle; float rightAngle = centerAngle; if (entitys.Count % 2 == 1) { Entity entity = entitys[centerIndex]; EntityLayoutParams layout = GetLayoutParams(entity.ViewSize); float offsetAngle = layout.GetAngleOffsetByRadius(entity.Radius); entity.Angle = centerAngle; entity.Radius = layout.GetRadius(centerAngle); leftAngle += offsetAngle; rightAngle -= offsetAngle; } while (rightIndex >= 0) { Entity left = entitys[leftIndex]; EntityLayoutParams leftLayout = GetLayoutParams(left.ViewSize); float leftRadius = leftLayout.GetLeftRadius(leftAngle); float leftOffsetAngle = leftLayout.GetAngleOffsetByRadius(leftRadius); left.Radius = leftRadius; left.Angle = leftAngle + leftOffsetAngle; Entity right = entitys[rightIndex]; EntityLayoutParams rightLayout = GetLayoutParams(right.ViewSize); float rightRadius = rightLayout.GetRightRadius(rightAngle); float rightOffsetAngle = rightLayout.GetAngleOffsetByRadius(rightRadius); right.Radius = rightRadius; right.Angle = rightAngle - rightOffsetAngle; leftAngle += leftOffsetAngle * 2.0f; rightAngle -= rightOffsetAngle * 2.0f; leftIndex++; rightIndex--; } entitys.MaxAngle = leftAngle; entitys.MinAngle = rightAngle; }
/// <summary> /// 布局标记列表 /// </summary> /// <param name="entitys">标记列表</param> private void LayoutEntityList(EntityList entitys) { //确定初始属性 foreach (Entity entity in entitys) { EntityLayoutParams layout = GetLayoutParams(entity.ViewSize); Vector2 position = m_MainCamera.transform.InverseTransformPoint(entity.TargetPosition).normalized *layout.RingRadius; entity.Angle = Mathf.Atan2(position.y, position.x) * Mathf.Rad2Deg; entity.Radius = layout.GetRadius(entity.Angle); } //按角度排序 entitys.SortByAngle(); //按角度分组 for (int i = 0; i < entitys.Count; i++) { if (i == 0 || entitys[i].Angle != entitys[i - 1].Angle) { m_GroupedEntitys.Add(EntityList.Create()); } m_GroupedEntitys[m_GroupedEntitys.Count - 1].Add(entitys[i]); } //分组展开 for (int i = 0; i < m_GroupedEntitys.Count; i++) { LayoutEntityGroup(m_GroupedEntitys[i]); } //多层次组合,再展开 while (m_GroupedEntitys.Count > 1) { bool changed = false; //相邻组合并 for (int i = 0; i < m_GroupedEntitys.Count - 1; i++) { EntityList group = m_GroupedEntitys[i]; EntityList nextGroup = m_GroupedEntitys[i + 1]; if (group.MaxAngle >= nextGroup.MinAngle) { group.AddRange(nextGroup); group.MinAngle = Mathf.Min(group.MinAngle, nextGroup.MinAngle); group.MaxAngle = Mathf.Max(group.MaxAngle, nextGroup.MaxAngle); m_GroupedEntitys.Remove(nextGroup); EntityList.Recycle(nextGroup); changed = true; i--; } } //首尾合并 if (m_GroupedEntitys.Count > 1) { EntityList lastGroup = m_GroupedEntitys[m_GroupedEntitys.Count - 1]; EntityList firstGroup = m_GroupedEntitys[0]; float firstMinAngle = firstGroup.MinAngle + 360.0f; float firstMaxAngle = firstGroup.MaxAngle + 360.0f; if (lastGroup.MaxAngle >= firstMaxAngle) { lastGroup.MinAngle = Mathf.Min(lastGroup.MinAngle, firstMinAngle); lastGroup.MaxAngle = Mathf.Max(lastGroup.MaxAngle, firstMaxAngle); for (int j = 0; j < firstGroup.Count; j++) { Entity entity = firstGroup[j]; entity.Angle += 360.0f; lastGroup.Add(entity); } m_GroupedEntitys.Remove(firstGroup); EntityList.Recycle(firstGroup); changed = true; } } // if (changed) { for (int i = 0; i < m_GroupedEntitys.Count; i++) { EntityList group = m_GroupedEntitys[i]; group.SortByAngle(); LayoutEntityGroup(group); } } else { break; } } //回收组列表 for (int i = 0; i < m_GroupedEntitys.Count; i++) { EntityList.Recycle(m_GroupedEntitys[i]); } m_GroupedEntitys.Clear(); //应用坐标到视图 foreach (Entity entity in m_EdgeEntitys) { EntityLayoutParams layout = GetLayoutParams(entity.ViewSize); //Debug.LogWarning(entity.Angle); Vector3 pos = Quaternion.Euler(0, 0, entity.Angle) * (Vector3.right * layout.RingRadius); Vector2 arrowPosition = m_ScaleBox.InverseTransformPoint(m_Root.TransformPoint(pos)); arrowPosition = arrowPosition.normalized * (Mathf.Max(m_Root.rect.width, m_Root.rect.height) / 2); arrowPosition = m_Root.InverseTransformPoint(m_ScaleBox.TransformPoint(arrowPosition)); entity.View.anchoredPosition = arrowPosition; } }