TLDR Sao chép mã và sử dụng bằng cách viết - bắn cá đổi thưởng online
Trải nghiệm giải trí bắn cá đổi thưởng online hấp dẫn

Đạt được tính năng nhập emoji giống Slack trong thành phần Unity UI Text.

textToAddEmoji.Emojify();

Gần đây tôi đang làm một trò chơi nhỏ, ban đầu chỉ cần hiển thị Emoji ở một số đoạn văn bản để thể hiện cảm xúc của nhân vật, vì vậy tôi đã sử dụng chức năng Sprite của TextMesh Pro và tự thiết kế 8 Emoji. Sau đó chọn Texture, tạo mới một Sprite Asset, đặt là Sprite Asset mặc định rồi cấu hình thuộc tính text trong script TextMesh Pro UGUI:

<sprite=1><sprite=1><sprite=1>

Như vậy có thể hiển thị biểu tượng cảm xúc tương ứng với số thứ tự. Tuy nhiên, vấn đề của phương án này là TMP (Text Mesh Pro), dù là giải pháp hiển thị chữ vector, nhưng hỗ trợ tiếng Trung không tốt lắm, vì vậy trong các trường hợp có cả tiếng Anh và tiếng Trung, tôi cố gắng hạn chế sử dụng TMP mà chuyển sang Text tích hợp sẵn của Unity. Hơn nữa, Unity cũng gặp vấn luật chơi sicbo đề khi nhập emoji, không thể hiển thị ngay như hộp nhập thông thường, nên cần phải có một ký hiệu thay thế chuỗi emoji trong game. Đối với vấn đề trước, tôi đã tìm thấy Unity-UI-emoji, còn đối với vấn đề sau, tôi quyết định áp dụng giải pháp của Slack trên cơ sở Unity-UI-emoji.

Hình ảnh Slack giải thích tính năng này như sau: “Slack sử dụng mã emoji chuẩn được tìm thấy tại Emoji Cheat Sheet.” Emoji Cheat Sheet thực sự bắn cá đổi thưởng online cung cấp thông tin mà tôi cần, nhưng lại hiển thị bằng Flash. May mắn thay, tôi đã tìm thấy một kho GitHub có tên Emoji Alpha Codes, cung cấp hai định dạng csv và json, vì vậy tôi dùng MiniJSON để chuyển đổi thành từ điển C#. Ngoài ra, tôi cũng cần chuyển đổi ngược lại để tạo ra từ điển có alpha codes làm khóa và emoji làm giá trị.

using System.Linq;
public Dictionary<string,string> InitDict ()
{
    emojiCodeJSONTextAsset = (TextAsset)Resources.Load(emojiCodeJSONPath,typeof(TextAsset));
    deserializedEmojiCodeJSONObject = (Dictionary<string,object>)MiniJSON.Json.Deserialize(emojiCodeJSONTextAsset.text);
    _reversedCodeEmojiDict = new Dictionary<string, string>();
    List<string> arrayOfAllKeys = deserializedEmojiCodeJSONObject.Keys.ToList();
    foreach (string key in arrayOfAllKeys)
    {
        Dictionary<string,object> subDict = (Dictionary<string,object>)deserializedEmojiCodeJSONObject[key];
        string code = (string) subDict["alpha_code"];
        string unicodeKey = GetConvertedString(key);
        //Debug.Log ("Key " + code + " ForValue " + unicodeKey);
        _reversedCodeEmojiDict[code] = unicodeKey;
    }
    return _reversedCodeEmojiDict;
}
private static string GetConvertedString(string inputString)
{
    // Một số emoji có tên hình ảnh chứa '-' , ở đây cần tách thành hai chuỗi bắt đầu bằng '\U' và nối chúng lại
    char[] chars = { '-' };
    return string.Join(string.Empty, inputString.Split(chars).Select(hex => char.ConvertFromUtf32(Convert.ToInt32(hex, 16))).ToArray());
}

Sau khi hoàn thành từ điển, hãy xem qua kho GitHub này. Giải pháp của Unity-UI-emoji là đọc các Emoji trong Text và thay thế chúng bằng emSpace = '\u2001' để giữ nguyên độ dài của chữ, đồng thời tạo RawImage dưới lớp Text và đặt nó vào vị trí của emSpace. Vì tất cả các emoji đều được đóng gói thành một texture lớn, nên tất cả các RawImage vẫn sử dụng cùng một material, lý thuyết là sẽ tiết kiệm Draw Call, tuy nhiên tôi chưa kiểm tra điều này. Nhưng kho này có một vấn đề, trong các điều kiện Canvas / Text phức tạp, vị trí của Emoji bị sai. Khi thử nghiệm trong game của tôi, Emoji thường bay ra ngoài giao diện. Vì vậy, cần sửa đổi phương thức SetUITextThatHasEmoji. Tại đây, tôi cần tham chiếu đến một câu trả lời trên Stack Overflow và một kho BitBucket, sau đó chỉnh sửa theo mã nguồn của Unity repository:

// Một rawimage cho mỗi emoji
for (int j = 0; j < emojiReplacements.Count; j++)
{
    int emojiIndex = emojiReplacements[j].pos;
    if (emojiIndex * 4 < textGen.verts.Count)
    {
        GameObject newRawImage = GameObject.Instantiate(this.rawImageToClone.gameObject);
        newRawImage.transform.SetParent(textToEdit.transform);
        
        Vector2 locUpperLeft = new Vector2(textGen.verts[emojiIndex * 4].position.x, textGen.verts[emojiIndex * 4].position.y);
        Vector2 locBottomRight = new Vector2(textGen.verts[emojiIndex * 4 + 2].position.x, textGen.verts[emojiIndex * 4 + 2].position.y);
        
        Vector3 mid = (locUpperLeft + locBottomRight) / 2.0f;
        Vector3 size = locBottomRight - locUpperLeft;
        
        Rect inputRect = textToEdit.rectTransform.rect;
        // Lấy điểm neo của căn chỉnh văn bản trong không gian cục bộ
        Vector2 textAnchorPivot = GetTextAnchorPivot(textToEdit.alignment);
        Vector2 refPoint = Vector2.zero;
        refPoint.x = (textAnchorPivot.x == 1 ? inputRect.xMax : inputRect.xMin);
        refPoint.y = (textAnchorPivot.y == 0 ? inputRect.yMin : inputRect.yMax);
        Vector2 roundingOffset = textToEdit.PixelAdjustPoint(refPoint) - refPoint;
        IList<UIVertex> verts = textGen.verts;
        FontData fontData = FontData.defaultFontData;
        fontData.font = textToEdit.font;
        float pixelsPerUnit = 0.0f;
        var localCanvas = GameObject.Find("GameCanvas").GetComponent<Canvas>();
        if (!localCanvas)
        {
            pixelsPerUnit = 1.0f;
        }
        else if (!textToEdit.font || textToEdit.font.dynamic)
        {
            pixelsPerUnit = localCanvas.scaleFactor;
        }
        else
        {
            pixelsPerUnit = textToEdit.font.fontSize / (float)fontData.fontSize;
        }
        float unitsPerPixel = 1 / pixelsPerUnit;
        int vertCount = verts.Count - 4;
        if (roundingOffset != Vector2.zero)
        {
            mid *= unitsPerPixel;
            mid.x += roundingOffset.x;
            mid.y += roundingOffset.y;
        }
        else
        {
            mid *= unitsPerPixel;
        }
        
        Debug.Log ("EMOJI mid X" + mid.x + " Y " + mid.y + " Z " + mid.z);
        newRawImage.transform.localPosition = mid;
        
        RawImage ri = newRawImage.GetComponent<RawImage>();
        ri.uvRect = emojiRects[emojiReplacements[j].emoji];
        ri.rectTransform.pivot = new Vector2(0.0f,0.0f);
        ri.rectTransform.localScale = Vector3.one;
        ri.rectTransform.sizeDelta = Vector2.one * textToEdit.font.lineHeight * unitsPerPixel;
    }
}

Mã này khá bừa bộn, kèo cá cược bóng đá nhưng có thể hoạt động, tôi sẽ tái cấu trúc nó sau khi hoàn thành game. Tiếp theo là thêm một phương thức mở rộng cho UnityEngine.UI.Text, tôi đặt tên là Emojify();

static public void Emojify (this UnityEngine.UI.Text self)
{
    if (JZEmojiUITextManager.Instance.reversedCodeEmojiDict == null)
    {
        return;
    }
    string currentCodeBasedString = self.text;
    
    // Sử dụng regex để chuyển đổi emoji alpha code thành Unicode tương ứng
    Dictionary<string,string> map = (Dictionary<string,string>)JZEmojiUITextManager.Instance.reversedCodeEmojiDict;
    var regex = new Regex(string.Join("|",map.Keys.ToArray()));
    var newStr = regex.Replace(currentCodeBasedString, m => map[m.Value]);
    // Unicode từ lần đầu tiên chưa được Unescape, cần thay '\\' thành '\'
    Regex regex1 = new Regex (@"\\U([0-9A-F]{4})", RegexOptions.IgnoreCase);
    var newStrUnescape = regex1.Replace (newStr, match => ((char)int.Parse (match.Groups[1].Value,
        NumberStyles.HexNumber)).ToString ());
    JZEmojiUITextManager.Instance.StartCoroutine(JZEmojiUITextManager.Instance.SetUITextThatHasEmoji(self, newStrUnescape));
}

Còn về JZEmojiUITextManager, đó chỉ là một singleton đơn giản, dùng để tạo và lưu trữ từ điển vừa nêu, cũng như sao chép hầu hết các phương thức từ kho Unity-UI-emoji. Giờ đây có thể trực tiếp áp dụng cho bất kỳ thành phần Text nào:

textToAddEmoji.Emojify();

Ngoài ra, tôi đã thay thế hình ảnh Emoji của kho này, chuyển từ Twitter Emoji sang iOS Emoji, liên kết là github.com/iamcal/emoji-data. Hiện tại hiệu quả như sau:

Buổi sáng! Đây là điện thoại mới của bạn. 
:flag_us:
Bạn có thể trả lời tin nhắn mới bằng cách vuốt thẻ sang trái hoặc phải. Phản hồi khác nhau sẽ dẫn đến tác động khác nhau lên giá trị công ty và mức độ hạnh phúc của nhân viên.
Mục tiêu của chúng ta là đạt được giá trị 1 tỷ đô la vào cuối năm trong khi giữ chân nhân viên khỏi rời đi.

Sửa đổi lần cuối vào 2025-05-20

123win city luật chơi sicbo tai gem ban ca bắn cá đổi thưởng online ket qua vong 5 ngoai hang anh 2025 kèo cá cược bóng đá