Search Unity

Displaying kanji with furigana?

Discussion in 'Immediate Mode GUI (IMGUI)' started by JoeStrout, Sep 15, 2014.

  1. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Does anyone know of an easy script, plug-in, or obvious trick I'm overlooking to display Japanese text with furigana in Unity?

    (Furigana are the little phonetic character displayed above kanji when written horizontally, or to the right of the kanji when written vertically. They let you know how the characters are pronounced, and in many cases, that helps recognize the word if you don't happen to know the Chinese characters.)

    Thanks,
    - Joe
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Since I couldn't find anything off-the-shelf, I whipped out a little script to do this this morning. It only handles horizontal text at this point, and the code could certainly stand to be cleaned up a bit, but it demonstrates the basic idea. Here's the code:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3. using System.Text.RegularExpressions;
    4.  
    5. public class FuriganaText : MonoBehaviour {
    6.     public string text;
    7.     public Rect position;
    8.     public GUISkin skin;
    9.     public string textStyle = "Label";
    10.     public string furiStyle = "Furigana";
    11.     public float yOffset = 10;
    12.     static Regex furiRegex;
    13.  
    14.     void OnGUI() {
    15.         GUI.skin = skin;
    16.         if (furiRegex == null) {
    17.             furiRegex = new Regex("\\[(.*?):(.*?)\\]");
    18.         }
    19.         string cleanText;    // base text, without any furigana or markup
    20.         List<int> furiCharIndex = new List<int>();    // char index (in base text) where furigana appears
    21.         List<int> furiCharLen = new List<int>();    // length of base text the furigana is over
    22.         List<string> furiText = new List<string>();    // actual text of the furigana
    23.  
    24.         cleanText = text;
    25.         while (true) {
    26.             Match match = furiRegex.Match(cleanText);
    27.             if (!match.Success) break;
    28.             furiCharIndex.Add(match.Index);
    29.             furiText.Add(match.Groups[2].ToString());
    30.             furiCharLen.Add(match.Groups[1].Length);
    31.             cleanText = cleanText.Substring(0, match.Index) + match.Groups[1]
    32.                     + cleanText.Substring(match.Index + match.Length);
    33.         }
    34.  
    35.         GUIStyle textGUIStyle = skin.GetStyle(textStyle);
    36.         GUIContent cleanContent = new GUIContent(cleanText);
    37.         GUI.Label(position, cleanContent, textGUIStyle);
    38.  
    39.         GUIStyle furiGUIStyle = skin.GetStyle(furiStyle);
    40.         for (int i=0; i<furiCharIndex.Count; i++) {
    41.             Vector2 leftPos = textGUIStyle.GetCursorPixelPosition(position, cleanContent, furiCharIndex[i]);
    42.             Vector2 rightPos = textGUIStyle.GetCursorPixelPosition(position, cleanContent,
    43.                                                                    furiCharIndex[i] + furiCharLen[i]);
    44.             Rect r = new Rect(leftPos.x, leftPos.y - yOffset - 20, rightPos.x - leftPos.x, 20);
    45.             GUI.Label(r, furiText[i], furiGUIStyle);
    46.         }
    47.     }
    48. }
    49.  
    ...and here's an example of the result:


    This is with the Text set to "[日:に][本:ほん]での[生:せい][活:かつ]は[楽:たの]しいです。". As you can see, you just throw square brackets around any character that should have furigana, and within the square brackets, separate the base text from the furigana with a colon.

    I throw this out there in hopes of seeing more Japanese games including furigana to help us gaijin! :)

    (In case anyone in Japan is searching for this someday, here's some fodder for the search engines: 漢字 ふりがな 外人)
     
  3. tainguyenhuu

    tainguyenhuu

    Joined:
    Aug 26, 2017
    Posts:
    5
    What is Regex? (in static Regex furiRegex statement)
     
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    That is a "regular expressions" class built into .NET. It is used for searching for patterns within strings. Here is a good introduction.

    But note that the code above uses the old GUI system. I have not yet found a good solution for the modern UI system that was added in Unity 4.5.
     
    tainguyenhuu likes this.
  5. tainguyenhuu

    tainguyenhuu

    Joined:
    Aug 26, 2017
    Posts:
    5
  6. tainguyenhuu

    tainguyenhuu

    Joined:
    Aug 26, 2017
    Posts:
    5
    I can't see result image in
    "...and here's an example of the result:
    "
     
  7. tainguyenhuu

    tainguyenhuu

    Joined:
    Aug 26, 2017
    Posts:
    5
    JoeStrout, It is Oke! I done right! thank you very much!
     
    JoeStrout likes this.
  8. tainguyenhuu

    tainguyenhuu

    Joined:
    Aug 26, 2017
    Posts:
    5
    if we want to display Kanji in MultiLine by set Word Wrap property then we need add a statement follow:

    if (rightPos.x <= leftPos.x)
    {
    rightPos = new Vector2(position.x + position.width, leftPos.y);
    }

    and here's an my exam of the result:
    Kanji.png
     
    JoeStrout likes this.
  9. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    すごいです! Great work! ^_^
     
    tainguyenhuu likes this.
  10. NogeGames

    NogeGames

    Joined:
    Jun 16, 2016
    Posts:
    5
    karolwieczorek9 and JoeStrout like this.