示例#1
0
        void DrawUnityStandardTextLabels()
        {
            ResetDefaultCountryLabelOffset();

            if (meshRects == null)
            {
                meshRects = new List <MeshRect>(_countries.Length);
            }
            else
            {
                meshRects.Clear();
            }
            float mw = mapWidth;
            float mh = mapHeight;

            for (int countryIndex = 0; countryIndex < _countries.Length; countryIndex++)
            {
                Country country = _countries[countryIndex];
                if (country.hidden || !country.labelVisible || country.mainRegionIndex < 0 || country.mainRegionIndex >= country.regions.Count)
                {
                    continue;
                }

                Vector2 center = new Vector2(country.center.x * mapWidth, country.center.y * mh) + country.labelOffset;
                center += GetDefaultCountryLabelOffset(countryIndex);

                Region region = country.regions[country.mainRegionIndex];

                // Adjusts country name length
                string countryName = country.customLabel != null ? country.customLabel : country.name.ToUpper();
                bool   introducedCarriageReturn = false;
                if (countryName.Length > 15)
                {
                    countryName = BreakOneLineString(countryName);
                    introducedCarriageReturn = true;
                }

                // add caption
                GameObject textObj;
                TextMesh   tm;
                Renderer   tmRenderer;
                TextMesh   tmShadow = null;
                if (country.labelTextMeshGO == null)
                {
                    Color labelColor = country.labelColorOverride ? country.labelColor : _countryLabelsColor;
                    Font  customFont = country.labelFontOverride ?? labelsFont;
                    if ((object)customFont == null)
                    {
                        continue;
                    }
                    Material customLabelShadowMaterial = country.labelFontShadowMaterial ?? labelsShadowMaterial;
                    tm      = Drawing.CreateText(countryName, null, center, customFont, labelColor, _showLabelsShadow, customLabelShadowMaterial, _countryLabelsShadowColor, out tmShadow);
                    textObj = tm.gameObject;
                    country.labelTextMesh   = tm;
                    country.labelTextMeshGO = tm.gameObject;
                    tmRenderer = textObj.GetComponent <Renderer>();
                    Bounds bounds = tmRenderer.bounds;
                    country.labelMeshWidth  = bounds.size.x;
                    country.labelMeshHeight = bounds.size.y;
                    country.labelMeshCenter = center;
                    textObj.transform.SetParent(textRoot.transform, false);
                    textObj.transform.localPosition = center;
                    textObj.layer = textRoot.gameObject.layer;
                    if (_showLabelsShadow)
                    {
                        country.labelShadowTextMesh = tmShadow; //textObj.transform.Find ("shadow").GetComponent<TextMesh> ();
                        country.labelShadowTextMesh.gameObject.layer = textObj.layer;
                    }
                }
                else
                {
                    tm      = country.labelTextMesh;
                    textObj = tm.gameObject;
                    textObj.transform.localPosition = center;
                    tmRenderer = textObj.GetComponent <Renderer>();
                }

                float meshWidth  = country.labelMeshWidth;
                float meshHeight = country.labelMeshHeight;

                // adjusts caption
                Rect  rect = new Rect(region.rect2D.xMin * mw, region.rect2D.yMin * mh, region.rect2D.width * mw, region.rect2D.height * mh);
                float absoluteHeight;
                if (country.labelRotation > 0)
                {
                    textObj.transform.localRotation = Quaternion.Euler(0, 0, country.labelRotation);
                    absoluteHeight = Mathf.Min(rect.height * _countryLabelsSize, rect.width);
                }
                else if (rect.height > rect.width * 1.45f)
                {
                    float angle;
                    if (rect.height > rect.width * 1.5f)
                    {
                        angle = 90;
                    }
                    else
                    {
                        angle = Mathf.Atan2(rect.height, rect.width) * Mathf.Rad2Deg;
                    }
                    textObj.transform.localRotation = Quaternion.Euler(0, 0, angle);
                    absoluteHeight = Mathf.Min(rect.width * _countryLabelsSize, rect.height);
                }
                else
                {
                    absoluteHeight = Mathf.Min(rect.height * _countryLabelsSize, rect.width);
                }

                // adjusts scale to fit width in rect
                float adjustedMeshHeight = introducedCarriageReturn ? meshHeight * 0.5f : meshHeight;
                float scale = absoluteHeight / adjustedMeshHeight;
                if (country.labelFontSizeOverride)
                {
                    scale = country.labelFontSize;
                }
                else
                {
                    float desiredWidth = meshWidth * scale;
                    if (desiredWidth > rect.width)
                    {
                        scale = rect.width / meshWidth;
                    }
                    if (adjustedMeshHeight * scale < _countryLabelsAbsoluteMinimumSize)
                    {
                        scale = _countryLabelsAbsoluteMinimumSize / adjustedMeshHeight;
                    }
                }

                // stretchs out the caption
                float  displayedMeshWidth  = meshWidth * scale;
                float  displayedMeshHeight = meshHeight * scale;
                string wideName;
                int    times = Mathf.FloorToInt(rect.width * 0.45f / (meshWidth * scale));
                if (times > 10)
                {
                    times = 10;
                }
                if (times > 0)
                {
                    StringBuilder sb     = new StringBuilder();
                    string        spaces = new string(' ', times * 2);
                    for (int c = 0; c < countryName.Length; c++)
                    {
                        sb.Append(countryName[c]);
                        if (c < countryName.Length - 1)
                        {
                            sb.Append(spaces);
                        }
                    }
                    wideName = sb.ToString();
                }
                else
                {
                    wideName = countryName;
                }

                if (tm.text.Length != wideName.Length)
                {
                    tm.text             = wideName;
                    displayedMeshWidth  = tmRenderer.bounds.size.x * scale;
                    displayedMeshHeight = tmRenderer.bounds.size.y * scale;
                    if (_showLabelsShadow)
                    {
                        tmShadow.text = wideName;
                    }
                }

                // apply scale
                textObj.transform.localScale = new Vector3(scale, scale, 1);

                // Save mesh rect for overlapping checking
                if (country.labelOffset == Misc.Vector2zero)
                {
                    float    xMin = center.x - displayedMeshWidth * 0.5f;
                    float    yMin = center.y - displayedMeshHeight * 0.5f;
                    float    xMax = xMin + displayedMeshWidth;
                    float    yMax = yMin + displayedMeshHeight;
                    MeshRect mr   = new MeshRect(countryIndex, new Vector4(xMin, yMin, xMax, yMax));
                    meshRects.Add(mr);
                }
            }

            // Simple-fast overlapping checking
            int  cont        = 0;
            bool needsResort = true;

            int meshRectsCount = meshRects.Count;

            while (needsResort && ++cont < 10)
            {
                meshRects.Sort(overlapComparer);
                needsResort = false;
                for (int c = 1; c < meshRectsCount; c++)
                {
                    Vector4 r1 = meshRects[c].rect;
                    for (int prevc = c - 1; prevc >= 0; prevc--)
                    {
                        Vector4 r2       = meshRects[prevc].rect;
                        bool    overlaps = !(r2.x > r1.z || r2.z <r1.x || r2.y> r1.w || r2.w < r1.y);
                        if (overlaps)
                        {
                            needsResort = true;
                            int        thisCountryIndex = meshRects[c].entityIndex;
                            Country    country          = _countries[thisCountryIndex];
                            GameObject thisLabel        = country.labelTextMeshGO;

                            // displaces this label
                            float offsety = r1.w - r2.y;
                            offsety = Mathf.Min(country.regions[country.mainRegionIndex].rect2D.height * mh * 0.35f, offsety);
                            thisLabel.transform.localPosition = new Vector3(country.labelMeshCenter.x, country.labelMeshCenter.y - offsety, thisLabel.transform.localPosition.z);
                            float width  = r1.z - r1.x;
                            float height = r1.w - r1.y;
                            float xMin   = thisLabel.transform.localPosition.x - width * 0.5f;
                            float yMin   = thisLabel.transform.localPosition.y - height * 0.5f;
                            float xMax   = xMin + width;
                            float yMax   = yMin + height;
                            r1 = new Vector4(xMin, yMin, xMax, yMax);
                            meshRects[c].rect = r1;
                        }
                    }
                }
            }
        }