NGUI中计算UILabel中每个文字的具体位置

来源:互联网 发布:linux如何解压rar文件 编辑:程序博客网 时间:2024/04/27 15:21

在游戏中有时候会碰到这样的需求,在Label中显示的文字中,部分文字需要有交互效果,比如点击地图位置文字可以自动寻路,点击聊天信息中的道具名称可以显示道具详情之类的。
解决这类问题,要么是将相应的文字做成button覆盖在文字上方,或者直接在对应的文字位置设置碰撞框,添加点击事件。不管如何都需要计算出label中一些特定文字的相对位置,才可以将碰撞框(或者表情之类的图片)放到正确的位置。
NGUI本身带有计算位置和显示文字大小的方法,NGUIText.CalculatePrintedSize和NGUIText.PrintExactCharacterPositions,这里需要将这些方法改编一下

    //计算单个文字的准确位置    //参数1是显示字符串的UI控件,参数2是要显示的所有文字,参数3是要计算位置的文字的index    public static Vector2 CalculateSinglePosition(UILabel label, string text, int index)    {        BetterList<Vector3> verts = new BetterList<Vector3>();        BetterList<int> indices = new BetterList<int>();        UpdateCharacterPosition(label, text, out verts, out indices);        index = indices.IndexOf(index);        Vector3 p1;        if (index != -1 && verts.size > index * 2 + 1)        {            p1 = (verts[index * 2] + verts[index * 2 + 1]) * 0.5f;        }        else        {            p1 = (verts[verts.size - 1] + verts[verts.size - 2]) * 0.5f;        }        return p1;    }    //计算显示文字的实际显示范围    //这个方法可以计算出整个文本的大小,NGUIText.CalculatePrintedSize的计算结果会有问题    public static Vector2 CalculatePrintedSize(UILabel label, string text)    {        float minX = 0, maxX = 0, minY = 0, maxY = 0;        BetterList<Vector3> verts = new BetterList<Vector3>();        BetterList<int> indices = new BetterList<int>();        UpdateCharacterPosition(label, text, out verts, out indices);        foreach (Vector3 cor in verts)        {            if (cor.x < minX)                minX = cor.x;            if (cor.x > maxX)                maxX = cor.x;            if (cor.y < minY)                minY = cor.y;            if (cor.y > maxY)                maxY = cor.y;        }        return new Vector2(maxX - minX, maxY - minY);    }    public static void UpdateCharacterPosition(UILabel label, string str, out BetterList<Vector3> verts, out BetterList<int> indices)    {        //计算当前所有字符的位置          label.text = str;        label.UpdateNGUIText();        BetterList<Vector3> tempVerts = new BetterList<Vector3>();        BetterList<int> tempIndices = new BetterList<int>();        NGUIText.PrintExactCharacterPositions(str, tempVerts, tempIndices);        verts = tempVerts;        indices = tempIndices;        for (int i = 0; i < verts.size; i++)        {            switch (label.pivot)            {                case UIWidget.Pivot.TopLeft:                    {                        verts[i] += new Vector3(0, 0, 0);                        break;                    }                case UIWidget.Pivot.Top:                    {                        verts[i] += new Vector3(-label.width * 0.5f, 0, 0);                        break;                    }                case UIWidget.Pivot.TopRight:                    {                        verts[i] += new Vector3(-label.width, 0, 0);                        break;                    }                case UIWidget.Pivot.Left:                    {                        verts[i] += new Vector3(0, label.height * 0.5f, 0);                        break;                    }                case UIWidget.Pivot.Center:                    {                        verts[i] += new Vector3(-label.width * 0.5f, label.height * 0.5f, 0);                        break;                    }                case UIWidget.Pivot.Right:                    {                        verts[i] += new Vector3(-label.width, label.height * 0.5f, 0);                        break;                    }                case UIWidget.Pivot.BottomLeft:                    {                        verts[i] += new Vector3(0, label.height, 0);                        break;                    }                case UIWidget.Pivot.Bottom:                    {                        verts[i] += new Vector3(-label.width * 0.5f, label.height, 0);                        break;                    }                case UIWidget.Pivot.BottomRight:                    {                        verts[i] += new Vector3(-label.width, label.height, 0);                        break;                    }            }        }    }

这里第一个方法计算出来的位置坐标,需要将碰撞框作为该Label的child object放到它下面再设置localPosition,这里算出的位置是该文字的中心位置。UpdateCharacterPosition算出的verts列表是每个文字的左下和右上坐标,indices列表是文字列表,所以verts中的元素个数总是indices的两倍。通过verts也可以算出每个文字的实际显示大小,有需要这个数据的可以自己写一下方法。

0 0
原创粉丝点击