• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            l

            成都手游碼農(nóng)一枚
            隨筆 - 32, 文章 - 0, 評論 - 117, 引用 - 0
            數(shù)據(jù)加載中……

            [Unity3D] RichText 圖標擴展的簡單實現(xiàn)

            方法一:
            利用 Horizontal Layout & Vertical Layout 布局。
            大概Lyaout控件結(jié)構(gòu):
            ----V
            ----H
            ----Text|Icon|Text|Icon
            ----H
            ----Text|Icon|Text|Icon
            ----H
            ----Text|Icon|Text|Icon
            ----H
            ----Text|Icon|Text|Icon
            方法簡答,缺點換行不易處理(需要拆分字符串獲取長度換行),且性能較差。
              1 public class BattleLogManager : MonoBehaviour 
              2 {
              3 
              4     public static BattleLogManager Instance;
              5 
              6     public GameObject mContent;
              7     // 行預制體
              8     public GameObject[] mItemPrefabs;
              9     public UISpriteSet mSpriteSet;
             10     public Font mFont;
             11     public int mFontSize = 35;
             12 
             13     private float mLineWidth = 600;
             14 
             15     void Start()
             16     {
             17         
             18         mLineWidth = ((mContent.transform as RectTransform).rect.width);
             19     }
             20 
             21     void OnDestroy()
             22     {
             23         Instance = null;
             24     }
             25 
             26     void OnEnable()
             27     {
             28         Instance = this;
             29     }
             30 
             31     // 特別注意:Text本身的RichText標簽要過濾掉才能計算字符串寬度從而判斷是不是需要換行
             32     int AppendText(GameObject go, string str, float offset, out float width, out string richToken)
             33     {
             34         var objTr = new GameObject("item").transform;
             35 
             36         CharacterInfo ci;
             37         var i = 0;
             38 
             39         richToken = "";
             40         width = 0.0f;
             41         for (; i < str.Length; ++i)
             42         {
             43             var ch = str[i];
             44 
             45             if (ch == '<' && i < str.Length - 1 && str[i + 1] != '/')
             46             {
             47                 var j = i + 1;
             48                 for (; j < str.Length; ++j)
             49                 {
             50                     if (str[j] == '>')
             51                     {
             52                         break;
             53                     }
             54                 }
             55 
             56                 if (j < str.Length)
             57                 {
             58                     richToken = str.Substring(i, j - i + 1);
             59                     i = j + 1;
             60                 }
             61             }
             62 
             63             if (ch == '<' && i < str.Length - 7 && str[i + 1] == '/')
             64             {
             65                 richToken = "";
             66                 i += 8;
             67             }
             68 
             69             if (i >= str.Length)
             70             {
             71                 if (string.IsNullOrEmpty(richToken))
             72                 {
             73                     Global.Log("bad rich format!");
             74                 }
             75                 break;
             76             }
             77 
             78             ch = str[i];
             79 
             80             mFont.GetCharacterInfo(str[i], out ci);
             81             var advance = ci.advance * (mFontSize / 32.0f);
             82             if (width + advance + offset > mLineWidth)
             83             {
             84                 break;
             85             }
             86             width += advance;
             87         }
             88 
             89         var newStr = (i == str.Length ? str : str.Substring(0, i)) + (string.IsNullOrEmpty(richToken) ? "" : "</color>");
             90 
             91         objTr.SetParent(go.transform);
             92         objTr.localPosition = Vector3.zero;
             93         objTr.localScale = Vector3.one;
             94         objTr.localRotation = Quaternion.identity;
             95 
             96         var text = objTr.gameObject.AddComponent<UnityEngine.UI.Text>();
             97 
             98         text.font = mFont;
             99         text.fontSize = mFontSize;
            100         text.alignment = TextAnchor.MiddleCenter;
            101         text.text = newStr;
            102         text.horizontalOverflow = HorizontalWrapMode.Overflow;
            103 
            104         return i;
            105     }
            106 
            107     bool AppendIcon(GameObject go, string icon, float offset, out float width)
            108     {
            109         Material material;
            110         var sprite = mSpriteSet.Get(icon, out material);
            111 
            112         width = 0;
            113         if (!sprite)
            114         {
            115             return true;
            116         }
            117 
            118         width = sprite.rect.width;
            119 
            120         if (offset + width > mLineWidth)
            121         {
            122             return false;
            123         }
            124         else
            125         {
            126             var objTr = new GameObject("item").transform;
            127 
            128             objTr.parent = go.transform;
            129             objTr.localPosition = Vector3.zero;
            130             objTr.localScale = Vector3.one;
            131             objTr.localRotation = Quaternion.identity;
            132 
            133             var image = objTr.gameObject.AddComponent<UnityEngine.UI.Image>();
            134 
            135             image.sprite = sprite;
            136             image.material = material;
            137             image.SetNativeSize();
            138         }
            139 
            140         return true;
            141     }
            142 
            143     void InnerInsertBattleLog(int itemPrefabIndex, string str, int alignment, float offset)
            144     {
            145         var itemObjectTr = Instantiate(mItemPrefabs[itemPrefabIndex]).transform;
            146 
            147         itemObjectTr.SetParent(mContent.transform);
            148         itemObjectTr.localPosition = Vector3.zero;
            149         itemObjectTr.localScale = Vector3.one;
            150         itemObjectTr.localRotation = Quaternion.identity;
            151         itemObjectTr.GetComponent<UnityEngine.UI.HorizontalLayoutGroup>().childAlignment = (TextAnchor)alignment;
            152 
            153         var textStart = 0;
            154 
            155         for (var i = 0; i < str.Length; )
            156         {
            157             if (i < str.Length - 1 && str[i] == '$' && str[i + 1] == '<')
            158             {
            159                 var iconStart = i + 2;
            160                 var iconEnd = -1;
            161 
            162                 for (var j = iconStart; j < str.Length; ++j)
            163                 {
            164                     if (str[j] == '>')
            165                     {
            166                         iconEnd = j;
            167                         break;
            168                     }
            169                 }
            170 
            171                 if (iconEnd != -1)
            172                 {
            173                     if (textStart != iconStart - 2)
            174                     {
            175                         var width = 0.0f;
            176                         string richToken = null;
            177                         var subEndIndex = AppendText(itemObjectTr.gameObject, str.Substring(textStart, iconStart - 2 - textStart), offset, out width, out richToken);
            178 
            179                         offset += width;
            180                         if (subEndIndex < iconStart - 2 - textStart)
            181                         {
            182                             InnerInsertBattleLog(itemPrefabIndex, richToken + str.Substring(textStart + subEndIndex, str.Length - (textStart + subEndIndex)), alignment, 0);
            183                             return;
            184                         }
            185                     }
            186 
            187                     // new line
            188                     {
            189                         var width = 0.0f;
            190 
            191                         if (!AppendIcon(itemObjectTr.gameObject, str.Substring(iconStart, iconEnd - iconStart), offset, out width))
            192                         {
            193                             InnerInsertBattleLog(itemPrefabIndex, str.Substring(iconStart - 2, str.Length - (iconStart - 2)), alignment, 0);
            194                             return;
            195                         }
            196                         offset += width;
            197                     }
            198 
            199                     i = iconEnd + 1;
            200                     textStart = i;
            201                 }
            202                 else
            203                 {
            204                     ++i;
            205                 }
            206             }
            207             else
            208             {
            209                 ++i;
            210             }
            211         }
            212 
            213         if (textStart < str.Length)
            214         {
            215             var width = 0.0f;
            216             string richToken = null;
            217             var subEndIndex = AppendText(itemObjectTr.gameObject, str.Substring(textStart, str.Length - textStart), offset, out width, out richToken);
            218 
            219             offset += width;
            220             if (subEndIndex < str.Length - textStart)
            221             {
            222                 InnerInsertBattleLog(itemPrefabIndex, richToken + str.Substring(textStart + subEndIndex, str.Length - textStart - subEndIndex), alignment, 0);
            223                 return;
            224             }
            225         }
            226     }
            227 
            228     public void InsertBattleLog(int itemPrefabIndex, string str, int alignment)
            229     {
            230         InnerInsertBattleLog(itemPrefabIndex, str, alignment, 0);
            231     }
            232 
            233     public void ClearAllLog()
            234     {
            235         for (var i = mContent.transform.childCount - 1; i >= 0; --i)
            236         {
            237             Destroy(mContent.transform.GetChild(i).gameObject);
            238         }
            239     }
            240 }
            241 

            方法二:
            1.利用FontCreator查找多余可利用字符編碼。
            例如:E7CC-E7D6



            2.合成ICON圖集,只支持一張,注意:貼圖尋址模式必須是 Repeat ,因為ICON uv會被重置為大于1,而字體貼圖尋址模式必須是 Clamp 。
            例如:

            3.使用新的字體材質(zhì)。

            1 fixed4 frag (v2f i) : SV_Target
            2 {
            3     fixed4 col = i.color;
            4     col.a *= tex2D(_MainTex, i.texcoord).a;
            5     // 當檢測到 uv.x > 1 是說明是被重置的對象 那么選取 Icon 貼圖進行顯示
            6     return lerp(col, tex2D(_IconTex, i.texcoord), step(1, i.texcoord.x));
            7 }

            4.啟動時候重新映射特殊字符UV E7CC-E7D6
             1 public class BattleLogManager : MonoBehaviour
             2 {
             3 
             4     public static BattleLogManager Instance;
             5 
             6     public UnityEngine.UI.Text mContent;
             7 
             8     private System.Text.StringBuilder mStringBuilder = new System.Text.StringBuilder();
             9     private bool mIsDirty = false;
            10 
            11     void OnDestroy()
            12     {
            13         Instance = null;
            14     }
            15 
            16     void OnEnable()
            17     {
            18         Instance = this;
            19     }
            20 
            21     public void InsertBattleLog(int itemPrefabIndex, string str, int alignment)
            22     {
            23         // 大字符串合并
            24         mStringBuilder.AppendLine(str);
            25         // mIsDirty 避免在同一幀內(nèi)多次調(diào)用重新設(shè)置UI文本
            26         mIsDirty = true;
            27     }
            28 
            29     public void ClearAllLog()
            30     {
            31         mStringBuilder = new System.Text.StringBuilder();
            32         mContent.text = "";
            33         mIsDirty = false;
            34     }
            35 
            36     public void LateUpdate()
            37     {
            38         if (mIsDirty)
            39         {
            40             mIsDirty = false;
            41             mContent.text = mStringBuilder.ToString();
            42         }
            43     }
            44 }

             1 public class RichTextConfig : MonoBehaviour 
             2 {
             3 
             4     public Font font;
             5     public int richIconTextureWidth = 256;
             6     public int richIconTextureHeight = 128;
             7 
             8     [System.Serializable]
             9     public struct Item
            10     {
            11         public int index;
            12         public Sprite sprite;
            13     }
            14 
            15     public Item[] items;
            16 
            17     void Start () 
            18     {
            19         DontDestroyOnLoad(this);
            20 
            21         Build();
            22     }
            23 
            24     [ContextMenu("build")]
            25     private void Build()
            26     {
            27         var ci = font.characterInfo;
            28 
            29         for (var i = 0; i < ci.Length; ++i)
            30         {
            31             for (var j = 0; j < items.Length; ++j)
            32             {
            33                 if (ci[i].index == items[j].index)
            34                 {
            35                     var rect = items[j].sprite.textureRect;
            36                     ci[i].uv = new Rect(2 + rect.x / richIconTextureWidth, rect.y / richIconTextureHeight, rect.width / richIconTextureWidth, rect.height / richIconTextureHeight);
            37                 }
            38             }
            39         }
            40 
            41         font.characterInfo = ci;
            42     }
            43 
            44 }
            45 



            5.字體材質(zhì)使用新的材質(zhì)

            posted on 2016-05-22 18:27 l1989 閱讀(3315) 評論(0)  編輯 收藏 引用 所屬分類: 游戲

            亚洲国产精品久久久久| 97久久超碰国产精品2021| 久久精品综合一区二区三区| 亚洲国产精品嫩草影院久久| 久久综合精品国产二区无码| 亚洲国产精品成人AV无码久久综合影院| 欧美日韩精品久久久久| 国产日产久久高清欧美一区| 久久亚洲欧美国产精品| 久久久青草久久久青草| 国产精品久久久久久| 精品久久久久久99人妻| 久久中文字幕一区二区| 久久福利资源国产精品999| 亚洲国产日韩欧美久久| 国产欧美久久一区二区| 77777亚洲午夜久久多喷| 久久精品国产久精国产一老狼| 久久99热这里只频精品6| 精品精品国产自在久久高清| 精品久久亚洲中文无码| 久久精品中文字幕有码| 久久99国产精品久久99果冻传媒| 亚洲中文字幕无码久久2017| 性做久久久久久久久老女人| 国产精品成人久久久久久久| 久久精品亚洲男人的天堂| 久久精品国内一区二区三区| 伊人久久精品无码av一区| 中文成人无码精品久久久不卡| 精品国产一区二区三区久久蜜臀| 久久九九青青国产精品| 久久99精品国产99久久6男男| 国产午夜免费高清久久影院| 99久久伊人精品综合观看| 久久99国产亚洲高清观看首页| jizzjizz国产精品久久| 麻豆精品久久久一区二区| 久久av免费天堂小草播放| 精品人妻伦九区久久AAA片69| 久久精品国产精品亚洲人人 |