トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

unity_ngui_label

[NGUI] テキストの表示(Label)


テキストの表示はLabelで行います。
フォントの指定、配置位置の変更、効果として影付け/縁取りなどが指定できます。


 配置

メインメニューより、「NGUI」-「Create」-「Label」よりラベルを配置します。

 フォントの指定

ラベルのInspectorウィンドウで、UILabelの一番上の項目で「Dynamic」を選択。
左上の「Font」をクリックして表示されるウィンドウ内で、Arialのある行の右端の「Select」を選択。これで、日本語も表示可能になります。

テキストエリアにテキストを入れるとそれが反映されます。
日本語などの全角を指定する場合は入力できないため(入力できる場合もありましたが、法則は分からず)、他のテキストエディタからコピー&ペーストするのがよいかと思います。

「Font Size」でフォントのサイズ指定が可能。
その右のポップアップリストでNormal/Bold/Italic/BoldAndItalicのフォントの種類を指定できます。

 テキスト効果

UILabelのEffectのポップアップリスト内のNone/Shadow/Outlineから選択できます。

影の落ちるずれやアウトラインの太さ、影/アウトラインの色を調整できます。

 表示位置の変更

デフォルトではテキストは配置したラベルの中央に表示されます。
これを左上に変更するには、UILabel内のWidgetのPivotで指定します。

Pivotの左の3つのボタンが水平方向の位置指定、右の3つのボタンが垂直方向の位置指定になります。

 テキスト内の一部の色を変更

テキストの指定で、

[RRGGBB]何か文字列[-]

のように、[ ] で囲って16進数でRed/Green/Blueの値を指定、末端で[-]を指定すると、その間のテキストは指定の色になります。


 スクリプトからテキストを指定

日本でよくあるアドベンチャー/ノベルゲームなどのようなテキストを表示する場合は、スクリプトでテキストを流し込むことになると思います。

以下は、Label1という名称のNGUIのLabelを取得して、テキストを「何かテキスト」と変更する例です。

GameObject gLabel1 = GameObject.Find("Label1") as GameObject;
if (gLabel1 != null) {
  UILabel label = gLabel1.GetComponent("UILabel") as UILabel;
  if (label != null) {
    label.text = "何かテキスト";
  }
}

改行は普通に「\n」を指定します。

 テキストを1文字ずつ徐々に表示

これもゲームではよくある手法ですが、時間とともに1文字ずつ表示させます。
スクリプトで一定時間ごとにテキストを表示していきます。

// 表示するテキスト.
private string m_textStr = "テキストを表示するときに、時間によりジョジョに表示させます。";

private int m_textPos = 0;   // 表示テキスト位置.
private int m_curTim  = 0;   // 時間計測のタイミング用.

// はじめに呼ばれる.
void Start () {
  {
    GameObject gLabel1 = GameObject.Find("Label1") as GameObject;
    if (gLabel1 != null) {
      UILabel label = gLabel1.GetComponent("UILabel") as UILabel;
      if (label != null) label.text = "";
    }
    m_textPos = 0;
    m_curTim  = 0;
  }
}  
 
// 更新時に呼ばれる.
void Update () {
  // 現在の経過時間をms(ミリ秒)で取得.
  int nowTim = (int)(Time.realtimeSinceStartup * 1000.0f);

  // 経過時間が250ms以上で更新.
  if (nowTim - m_curTim >= 250) { 
    m_curTim = nowTim;
    if (m_textPos <= m_textStr.Length) {
      // テキストを取り出す.
      string str = m_textStr.Substring(0, m_textPos);

      // テキストを更新.
      GameObject gLabel1 = GameObject.Find("Label1") as GameObject;
      if (gLabel1 != null) {
        UILabel label = gLabel1.GetComponent("UILabel") as UILabel;
        if (label != null) label.text = str;
      }

      m_textPos++;
    }
  }
}

これを実行すると、Label1という名称のLabelに「テキストを表示するときに、時間によりジョジョに表示させます。」というテキストを1文字ずつ表示していきます。
これにあわせて、Soundの「ポポポポ、、、」を再生するとそれらしいかもしれません。

 禁則処理はどうする?


UILabelでは、日本語での禁則処理(。、っ などが行の先頭に来ないようにする)には対応していないようでした。
たとえば、スクリーン幅によっては以下のようになってしまいます。


この部分を細工。
UILabel.Wrapで第一引数で指定した文字列を折り返した後の文字列を取得できます。
この際に、追加された改行は「\n」。これを利用。
なお、あらかじめLabelの原点は左上になるようにしておいてください。

強引に以下のスクリプトを作りました。

/**
 * 日本語禁則処理を行ったテキストを返す.
 */
private string m_ConvWrapText(UILabel label, string orgText) {
   string orgStr = orgText;
   
   {
       // 文字の折り返しを考慮したテキストを取得 (この段階では禁則処理されてない).
       string wrapStr = "";
       if (!label.Wrap(orgStr, out wrapStr)) { wrapStr = label.text; }
       if (wrapStr.Equals(orgStr)) return orgStr;
   }
   
   //--------------------------------------------
   // 元のテキストを改行で分割して、それぞれで折り返しチェック.
   //--------------------------------------------
   // 「\r\n」(CRLF)でのよくある改行コードを「\n」に統一.
   string str = orgStr.Replace("\r\n", "\n");
   
   // 禁則処理で先頭に来てはいけない文字.
   string kinsokuStr = "、。)」』ぁぃぅぇぉっゃゅょゎァィゥェォッャュョヮヵヶ";
   
   while (true) {
       string [] strArray = str.Split('\n');
       string wrapStrE = "";
   
       string newStr = "";
       for (int i = 0; i < strArray.Length; i++) {
           if (i > 0) newStr += "\n";
   
           // 文字列の折り返し処理を行う.
           string strL = strArray[i];
           if (!label.Wrap(strL, out wrapStrE)) { wrapStrE = strL; }
   
           // 折り返し処理が行われていない場合はそのまま追加.
           if (wrapStrE.Equals(strL)) {
               newStr += strL;
               continue;
           }
   
           // 改行で分離.
           string [] strLineArray = wrapStrE.Split('\n');
   
           // 個々の行の先頭に来てはいけない文字があるかチェックし、連結.
           string newLineStr = "";
           for (int j = 0; j < strLineArray.Length; j++) {
               string strLine = strLineArray[j];       // 1ライン分.
               string str0    = strLine[0].ToString(); // 先頭の1文字.
               if (newLineStr.Length > 0 && kinsokuStr.IndexOf(str0) >= 0) {   // 先頭に来てはいけない文字が見つかった.
                   string lastStr = newLineStr.Substring(newLineStr.Length - 1, 1);
                   newLineStr = newLineStr.Substring(0, newLineStr.Length - 1);
                   strLine    = lastStr + strLine;
               }
               if (newLineStr.Length > 0) newLineStr += "\n";
               newLineStr += strLine;
           }
           newStr += newLineStr;
       }
   
       // 折り返し処理を行い、折り返しが不要の場合は抜ける.
       str = newStr;
       if (!label.Wrap(str, out wrapStrE)) { wrapStrE = str; }
       if (str.Equals(wrapStrE)) break;
   }
   
   return str;
}

オリジナルのUILabelで指定されたテキストで、すでに行頭でルールに反した文字(、や。など)を指定している場合は正しく動作しません。

NGUIText.WrapText UILabel.Wrap関数を使用することで、NGUIでの折り返し処理を行ったテキストが返されます。
オリジナルのテキストがこれと同じ場合はそのまま使用。
それ以外の場合は、ルールに即さない文字が文頭にあらわれるときに1つ前の行の末尾の文字を次の行に回す、としました。
ただ、これはかなり強引な付け刃ですが。

以下のように「/UI Root/message_label」で配置されているUILabel内のテキストを補正。

GameObject mainG = GameObject.Find("/UI Root/message_label") as GameObject;
UILabel label = mainG.GetComponent("UILabel") as UILabel;
string orgText = label.text;   // あらかじめ元のテキストを保持しておく.
 
// 以下をUpdate関数内で呼んでみました.
// なお、モバイルでは1回のUpdateだけでは正しくない矩形内で折り返しが.
// 起きることがあり、Updateを5ループくらいさせてその都度以下を呼ぶことで.
// 意図した配置になりました.
label.text = m_ConvWrapText(label, orgText);		// 日本語禁則処理での補正.

以下のように折り返しが補正されます。


ほんとは禁則の文字が行頭にする場合は、前の行の末尾に禁則文字を詰めてつけるようにしたほうがよさそうではあります。
このあたりは機会があれば掘ってみます。


最終更新時間:2014年04月21日 15時33分32秒