コンテンツクリック機能のUGUIテキスト部分(フルビジュアルバージョン)

PLAGame.BattleLogicを使用する;
PLAGame.Clientを使用する;
システムを使用する;
System.Collections.Genericを使用する;
System.Textを使用します。
System.Text.RegularExpressionsを使用する;
UnityEngineを使用する;
UnityEngine.Eventsを使用する;
UnityEngine.EventSystemsを使用する;
UnityEngine.UIを使用します。
Newtonsoft.Jsonを使用します。

名前空間UnityEngine.UI
{


    /// <summary>
    ///テキストコントロール、ハイパーリンクのサポート
    /// </ summary>
    public class HyperlinkText:Text、IPointerDownHandler、IPointerUpHandler、IPointerClickHandler
    {         /// <summary>         ///ハイパーリンク情報クラス         /// </ summary>         プライベートクラスHyperlinkInfo         {             public int startIndex;





            public int endIndex;

            パブリック文字列名;

            public readonly List <Rect> box = new List <Rect>();
        }
        /// <summary>
        ///最終テキストを解析した後
        /// </ summary>
        private string m_OutputText;

        /// <summary>
        ///ハイパーリンク情報リスト
        /// </ summary>
        プライベート読み取り専用リスト<HyperlinkInfo> m_HrefInfos = new List <HyperlinkInfo>();

        /// <summary>
        ///テキストコンストラクター
        /// </ summary>
        protected static readonly StringBuilder s_TextBuilder = new StringBuilder();


        [Serializable]
        public class HrefClickEvent:UnityEvent <string> {}
        [SerializeField]
        private HrefClickEvent m_OnHrefClick = new HrefClickEvent();

        [SerializeField]
        private HrefClickEvent m_OnHrefPress = new HrefClickEvent();

        /// <summary>
        ///ハイパーリンククリックイベント
        /// </ summary>
        public HrefClickEvent onHrefClick
        {             get {return m_OnHrefClick;}             set {m_OnHrefClick = value;}         }


        /// <summary>
        ///ハイパーリンククリックイベント
        /// </ summary>
        public HrefClickEvent onHrefPress
        {             get {return m_OnHrefPress;}             set {m_OnHrefPress = value;}         }


        public UnityEvent PointUpAction;

        /// <summary>
        ///超链接正则
        /// </ summary>
        private static readonly Regex s_HrefRegex = new Regex(@ "<a href =([^> \ n \ s] +)>(。*? )(</a>) "、RegexOptions.Singleline);

        プライベートHyperlinkTextmHyperlinkText;

        public string GetHyperlinkInfo
        {             get {return text; }         }         private bool isPointerDown = false;         プライベートフロート間隔= 0.3f;         プライベートフロートrecordTime;         プライベートVector2curlp;





        プライベートGameObjectexa;
        保護されたオーバーライド             voidAwake()
        { base.Awake();             mHyperlinkText = GetComponent <HyperlinkText>();


        }
        protected override void OnEnable()
        {             base.OnEnable();             mHyperlinkText.onHrefClick.AddListener(OnHyperlinkTextInfo);         }


        保護されたオーバーライドvoidOnDisable()
        {             base.OnDisable();             mHyperlinkText.onHrefClick.RemoveListener(OnHyperlinkTextInfo);

        }


        public override void SetVerticesDirty()
        {             base.SetVerticesDirty();

            text = GetHyperlinkInfo;
            m_OutputText = GetOutputText(text);

        }


        int getline(IList <UILineInfo> lines、int index)
        {             int line = 0;

            for(int i = 0; i <lines.Count; i ++)
            {                 var info = lines [i];                 if(index> info.startCharIdx * 4-3)                 {                     line = i + 1;                 }             }





            リターンライン;
        }

        保護されたオーバーライドvoidOnPopulateMesh(VertexHelper toFill)
        {             var orignText = m_Text;             m_Text = m_OutputText;             base.OnPopulateMesh(toFill);             m_Text = orignText;           // print($ "currentVertCount = {toFill.currentVertCount}、currentIndexCount = {toFill.currentIndexCount}");             var lines = cachedTextGeneratorForLayout.lines;             varvertexList = new List <UIVertex>();             UIVertex頂点=新しいUIVertex();             int rectCount = toFill.currentVertCount / 4;             Dictionary <int、int> afterindexofbeforeindex = new Dictionary <int、int>(); //后来的テクスチャ










            //https://www.zhihu.com/question/372690850
            //スペースブレークも頂点としてカウントされ、それらの座標は同じであるため
            、(int i = 0; i <rectCount; i ++)
            {                 int startIndex = i *のために削除します。4;                 toFill.PopulateUIVertex(参照頂点、startIndex);                 var p1 =頂点;                 toFill.PopulateUIVertex(参照頂点、startIndex + 1);                 var p2 =頂点;                 toFill.PopulateUIVertex(参照頂点、startIndex + 2);                 var p3 =頂点;                 toFill.PopulateUIVertex(refvertex、startIndex + 3);                 var p4 =頂点;








                if(p1.position!= p2.position &&
                    p2.position!= p3.position &&
                    p3.position!= p4.position)
                {                     afterindexofbeforeindex.Add(vertexList.Count、startIndex);                     afterindexofbeforeindex.Add(vertexList.Count + 1、startIndex + 1);                     afterindexofbeforeindex.Add(vertexList.Count + 2、startIndex + 2);                     afterindexofbeforeindex.Add(vertexList.Count + 3、startIndex + 3);                     VertexList.AddRange(new UIVertex [] {p1、p2、p3、p4});                 }





            }

        // Debug.Log($ "最適化前{toFill.currentVertCount}、最適化後{vertexList.Count}");
           //行間折り返しの問題は解決されません

            //ハイパーリンク境界ボックスを処理します
            Dictionary <int、List <Rect >> dicRect = new Dictionary <int、List <Rect >>();
            foreach(var hrefInfo in m_HrefInfos)
            {

                hrefInfo.boxes.Clear();
                dicRect.Clear();
               // print($ "startIndex = {hrefInfo.startIndex}");
                // int line = 1;
                //ハイパーリンクにテキスト頂点インデックス座標を追加しますRectには、テキストごとに4つの頂点があります           
                (int i = hrefInfo.startIndex、m = hrefInfo.endIndex; i <m; i + = 4)
                {                     if(i> = VertexList.Count)//表示されている部分のみがそれを超えて表示されます表示領域はBreak                     {                         break;                     }                     int line = getline(lines、afterindexofbeforeindex [i]); //行数を取得する                     必要があり                     ますRectrect = new Rect(); UIVertex vert1 = VertexList [i];







                    UIVertex vert3 = VertexList [i + 2];
                 
                    rect.width = Math.Abs​​(vert1.position.x --vert3.position.x);
                    rect.height = Math.Abs​​(vert1.position.y --vert3.position.y);
                    rect.x =(vert1.position.x + vert3.position.x)/ 2;
                    rect.y =(vert1.position.y + vert3.position.y)/ 2;
                    // print($ "i = {i}、rect = {rect.position}、vert1 = {vert1.position}、vert3 = {vert3.position}");
                    if(dicRect .Count> 0 &&(rect.y + 1 <dicRect [line] [dicRect [line] .Count-1] .y))
                    {                         line ++;                     }                     if(dicRect.ContainsKey(line))


               

                    {{

                        dicRect [line] .Add(rect);
                    }
                    else
                    {                         dicRect.Add(line、new List <Rect>(){rect});                     }                    // print($ "line = {line}、dicrectcount = {dicRect.Count}");                 }                // print(JsonConvert.SerializeObject(dicRect));                 foreach(dicRectのvar item)                 {                     // print($ "item key = {item.Key}、[f] = {item.Value [0] .position}、[l] = {item.Value [item.Value .Count-1] .position} ");                     Rect rect = new Rect();                     var f = item.Value [0];










                    var l = item.Value [item.Value.Count-1];
                    rect.width = Math.Abs​​(fx --lx)+ f.width / 2 + l.width / 2;
                    rect.height = f.height;
                    rect.x = fx +(lx-fx)/ 2;
                    rect.y = fy;
                   // print($ "last item key = {item.Key}、{rect.position}");
                    hrefInfo.boxes.Add(rect);
                }
            }
        }

        /// <summary>
        ///ハイパーリンクが解析された後の最終出力テキストを取得します
        /// </ summary>
        /// <returns> </ returns>
        protected virtual string GetOutputText(string outputText)
        {             s_TextBuilder.Length = 0;             m_HrefInfos.Clear();             var indexText = 0;             foreach(s_HrefRegex.Matches(outputText)の一致一致)             {




                s_TextBuilder.Append(outputText.Substring(indexText、match.Index-indexText));
                var group = match.Groups [1];
                var str = Regex.Replace(s_TextBuilder.ToString()、@ "\ s"、 "") ;
               // print($ "str = {str}");
                var hrefInfo = new HyperlinkInfo
                {                     //スペースを削除し、リッチテキスト識別子を正しい位置にラップします                           startIndex = Regex.Replace(str、@ "<(。*? )> "、" ")。Length* 4、//ハイパーリンク内のテキストの開始頂点インデックス                     endIndex =(Regex.Replace(str、@" <(。*?)> "、" ").Length +                     Regex .Replace(Regex.Replace(match.Groups [2] .ToString()、@ "\ s"、 "")                     、@ "<(。*?)>"、 "").Length-1)* 4 + 3、

                  




                    name = group.Value
                };
                m_HrefInfos.Add(hrefInfo);
                // print( "")
                s_TextBuilder.Append(match.Groups [2] .Value);
                indexText = match.Index + match.Length;
            }
            s_TextBuilder.Append(outputText.Substring(indexText、outputText.Length-indexText));
            s_TextBuilder.ToString();を返します。
        }


        RectTransform createImage(Transform parent)
        { GameObject             image = new GameObject();             var rect = image.AddComponent <RectTransform>();             var img = image.AddComponent <Image>();             img.raycastTarget = false;             img.color = new Color(1、1、1、0.4f);             image.transform.SetParent(parent);             image.transform.localPosition = Vector3.zero;             image.transform.localScale = Vector3.one;             rectを返す;         }








            

        void trigger(Action <string> cb、Vector2 lp)
        {             //画像サイズ2 * 2を作成して、クリックポイントを表示できますLp TO             var point = createImage(transform);             point.name = "clickpoint";             point.anchoredPosition = lp;             point.sizeDelta = Vector2.one * 2;             point.GetComponent <Image>()。color = Color.red;





            foreach(HyperlinkInfo hrefInfo in m_HrefInfos)
            {                 var box = hrefInfo.boxes;                // print($ "{Newtonsoft.Json.JsonConvert.SerializeObject(hrefInfo)}");                 for(var i = 0; i <boxes.Count; + + i)                 {                     print($ "boxes [{i}] = {boxes [i]}");                     //ボックス[i]の画像サイズを作成してクリック領域を表示できますTO //コメントでき                     ます// var box = createImage(transform);                   // box.name = "box" + hrefInfo.name;                    // box.sizeDelta = new Vector2(boxes [i] .width、boxes [i] .height);                 // box.anchoredPosition =新しいVector2(boxes [i] .x、boxes [i] .y);









                    if((boxes [i] .x --boxes [i] .width / 2)<lp.x &&(boxes [i] .x + boxs [i] .width / 2)> lp.x &&
                        (boxes [i ] .y --boxes [i] .height / 2)<lp.y &&(boxes [i] .y + boxs [i] .height / 2)> lp.y)
                    {                         print( "点击了" + hrefInfo。名前);                         cb(hrefInfo.name);                         戻る;                     }                 }             }         }






        public void OnPointerClick(PointerEventData eventData)
        {             Vector2 lp = Vector2.zero;             print( "eventData Camera" + eventData.pressEventCamera.name);             RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform、eventData.position、GameObject.FindGameObjectWithTag                  ( "UICamera")?GameObject.FindGameObjectWithTag( "UICamera")。GetComponent <Camera>()                  :eventData.pressEventCamera、out lp);             for(int i = transform.childCount --1; i> = 0; i-)             {                // DestroyImmediate(transform.GetChild(i).gameObject);             }             trigger((s)=> {m_OnHrefClick。呼び出す; }、lp);





           





        }

        public void OnPointerDown(PointerEventData eventData)
        {             recordTime = Time.time;             isPointerDown = true;             curlp = Vector2.zero;             RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform、eventData.position、eventData.pressEventCamera、out curlp);




        }

        public void OnPointerUp(PointerEventData eventData)
        {

            isPointerDown = false;
            PointUpAction.Invoke();
            for(int i = transform.childCount --1; i> = 0; i-)
            {                 // DestroyImmediate (transform.GetChild(i).gameObject);             }         }         void Update()         {             if(isPointerDown)             {                 if(Time.timeScale!= 1)                 {                     間隔= 0.6f;                 }                 else                 {                     間隔= 0.3f;                 }                 if((Time.time-recordTime)> interval)
















                {                     isPointerDown = false;                    // trigger((s)=> {m_OnHrefPress.Invoke(s);}、curlp);                                    }             }         }




        /// <summary>
        ///ハイパーリンクコールバックの現在のクリック
        /// </ summary>
        /// <
        paramname = "info">コールバック情報</ param> private void OnHyperlinkTextInfo(string info)
        {             // print( "クリック" +情報);         }

    }
}

おすすめ

転載: blog.csdn.net/weixin_41995872/article/details/109599612