今回の記事では文字列について解説していきます。
文字列を使えるようになると、アプリ上でテキストを表示できるようになります。
ゲーム内でメニュー画面の文字表示やダイアログメッセージを出したりする場合に必須ですね。
またそんな文字列を操作する文字列メソッドの解説も行います。メソッドに関しては前回の記事で解説しました。
前回の記事:
string型とは
string
型は文字列と呼ばれるC#の基本型の一つで参照型になります。その実体は文字型(char
)の配列になります。また、System.String
の別名になります。
コンピュータ上では文字は文字コードという数値と文字の対応表を使って表現されます。いくつか種類はあるのですが、C#ではUTF-16というUnicodeの一種を使用しています。
書き方
スクリプト上で文字列を表す際は文字を""
で括ってください。
- 書き方:
"<文字>..."
また、@""
や$""
など特殊な書き方もあります。
- @”<文字>…”:
""
の中の文字をそのまま文字列として扱う。後述するエスケープシーケンスはそのまま文字列として扱われます。ファイルパスなどに使用できます。 - $”<文字>…”:書式(Format)を埋め込むことができる文字列。
{}
で括った値を文字列に変換することができる。
1 2 3 |
string str = "ABC"; string str2 = @"Dir1\Dir2\File.txt"; string str3 = $"str = {str}"; |
エスケープシーケンスについて
文字には改行文字やタブなどそのままだと表現できない特殊な文字が存在します。プログラミングの世界ではそれらをエスケープシーケンスと呼んでいます。
エスケープシーケンスは\
(バックスラッシュ)で始まる2文字以上の文字列になります。スクリプト上では2文字以上ですが、データ上は1文字として扱われます。
@”<文字>…”を使用すると文字列中のエスケープシーケンスを無視し入力したままの文字を文字列だと解釈します。
1 |
string str = "\tABC\r\n"; |
エスケープシーケンスの一覧(公式ドキュメントから抜粋)
エスケープシーケンス | 名称 | ユニコードエンコード値 |
---|---|---|
\’ | シングルクォート | 0x0027 |
\” | ダブルクォート | 0x0022 |
\\ | バックスラッシュ | 0x005C |
\0 | ヌル文字 | 0x0000 |
\a | アラート音 | 0x0007 |
\b | バックスペース | 0x0008 |
\f | フォームフィード | 0x000C |
\n | 改行 | 0x000A |
\r | 行復帰 | 0x000D |
\t | 水平タブ | 0x0009 |
\v | 垂直タブ | 0x000B |
\u | ユニコードエスケープシーケンス (UTF-16) | \uHHHH (範囲: 0000 – FFFF; 例: \u00E7 = “ç”) |
\U | ユニコードエスケープシーケンス (UTF-32) | \U00HHHHHH (範囲: 000000 – 10FFFF; 例: \U0001F47D = “👽”) |
\x |
ユニコードエスケープシーケンス。\uと同じだがこちらは4文字書く必要はない。 |
\xH[H][H][H] (範囲: 0 – FFFF; 例: \x00E7 or \x0E7 or \xE7 = “ç”) |
書式について
他の型から文字列に変換する際、いくつかの型には書式という文字列に変換する方法を指定できるものがあります。
書式付きの変換にはstring.Format()
や$"<文字>..."
などが利用できます。
C#が用意しているものとしては以下があります。
- 数値型:何桁まで表示するか指定できたり、0埋めや16進数表記で変換など指定できる。
- System.DateTime:必要な日付情報のみ文字列に変換できる。”yyyy:MM:dd HH-mm-ss”で”2021:01:11 12-30-12″などとテキストに変換される。
などなど。
ここでは簡単にだけ紹介しています。まだまだ他の変換方法があります。詳しい情報は検索してみてください。
1 2 3 4 5 6 7 8 |
int a = 100; uint u = 0xf1f1 //書式を使って変数を文字列に変換している。 // -> str == "a = 0100, u = 0xf1f1" string str = $"a = {a:0000}, u = {u:x}"; //古い書き方。値を直接書くのではなく引数の番号を指定する形になる。 string str2 = string.Format("a = {0:0000}, u = {1:x}", a, u); |
色々な文字列処理用のメソッド
文字列には色々なメソッドが用意されていますので、ここで簡単に紹介します。
添字アクセス
配列と同じ様に文字列中の文字には<文字列>[<添字>]
とアクセスすることができます。
使い方や注意点は配列と同じになります。
1 2 3 |
string str = "ABC"; str[0] = 'Z'; // <- str == "ZBC"; char ch = str[1]; // <- ch == 'B' |
string型のメンバー
C#では文字列に以下の様なメンバーが用意されています。
メンバーは、C#のクラスや構造体や型に含まれるデータおよび動作を表すものです。
文字列は配列と同じなのでこれらのメンバを使う上では添字が必要になるものもあります。
また、ここで紹介したメンバーは他のプログラミング言語でも似たものが用意されていることが多いので一度覚えたら様々な言語で再利用できます。
数が多いのでざっと紹介するだけに留めておきます。詳しい使い方については公式ドキュメントを参考にするか、検索してみてください。
- Length:文字列の文字数を表すプロパティ。
- +演算子:末尾に文字列を追加することができる。
- Clone():文字列をコピーする。参照型なので
=
演算子では実態データはコピーされないのに注意。 - Concat():指定した文字列と合成できる。
- Contains():指定した文字・文字列が含まれているかどうか判定する。
- StartsWith():文字列の先頭が指定した文字・文字列と一致しているかどうか判定する。
- EndsWith():文字列の末尾が指定した文字・文字列と一致しているかどうか判定する。
- Format():他の型の値を書式付きで文字列に変換する。
$"<文字>..."
と同じものになる。 - Insert():指定した文字・文字列を指定した添字の位置に挿入する。
- Join():文字・文字列のリストを指定した区切り文字で結合する。
- IndexOf():指定した文字・文字列の頭文字が何番目にあるのか検索する。ない場合は-1を返す。
- LastIndex():IndexOfと同じで、こちらは最後に出てきた場所を返す。
- PadLeft():指定した文字数以上になる様に文字列を左に寄せる。
- PadRight():指定した文字数以上になる様に文字列を右に寄せる。
- Remove():指定した添字の範囲の文字を削除する。
- Replace():指定した文字・文字列を他の文字列に置き換える。
- Split():指定した文字で文字列を分割する。
- SubString():指定した添字の範囲を別の文字列として新しく作成する。
- ToLower():全ての文字を小文字にする。
- ToUpper():全ての文字を大文字にする。
- Trim():先頭と末尾に指定した文字が存在するなら、その文字を全て削除する。
- TrimStart():Trim()の先頭のみ削除するもの。
- TrimEnd():Trim()の末尾のみ削除するもの。
これ以外にも検索・置き換え機能を高機能化した正規表現というものもありますが、ここでは割愛します。
文字列型から数値型の変換について
文字列から数値型に変換する際は専用のメソッドがC#には用意されていますのでそちらを使用してください。
メソッドは全ての数値型の静的メソッド(※)として定義されています。変換メソッドは大きく分けて例外を投げるParse()メソッドとbool型の戻り値を返すTryParse()メソッドがあります。
(※クラスのメンバーの分類の一つになります。アプリ上どこからでも使うことができるメンバになります。)
1 2 3 4 5 6 7 8 9 10 11 12 |
int a = 100; var str = a.ToString(); //<数値型名>.Parse()で対応した数値型へ変換できる。 // もし、変換できない文字列の場合は例外が発生する。 var A = int.Parse(str); bool OK = (a == A); // <= true //こちらはTryParse()を使用している。 // 変換できたときはtrueを戻り値として返し、できなかったときはfalseを返す。 if(int.TryParse(str, out var AA)) { bool OK2 = (a == AA); // <- true } |
文字列を他の型へ変換する場合はシリアライズ(Serialize)と呼ばれる処理で相互変換することができますが、ここでは紹介だけに留めておきます。
System.Text.StringBuilderについて
string
型の操作はC#的に負荷が高いものになります。そのため処理負荷が気になる場合はSystem.Text.StringBuilder
クラスというものが用意されています。
使い方は生成したいテキストをAppend()メソッドで設定し、ToString()メソッドで文字列を作成します。一度設定したものを削除したいときはClear()メソッドを使用してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
using System.Text; var builder = new StringBuilder(); builder.Append("ABC"); builder.Append(" unity"); builder.Append(" C#"); builder[0] = "z"; //ToString()で設定してきた文字列を出力する。 // str == "zBC unity C#" var str = builder.ToString(); //Clearメソッドで設定してきた文字列をクリアーする builder.Clear(); var str2 = builder.ToString(); // <- str2 == ""; |
【実践】Unityスクリプトの中で文章を使ってみる
ここまで文字列について説明してきました。Unityで画面上に表示するにはFontや専用のコンポーネントが必要になってきます。
今回のサンプルコードではTextMeshコンポーネントを使用し、Inspector上から複数のテキストを設定。その後に再生ボタンを押したら、それらの文字を合成して画面に表示していきます。
それでは先にサンプルコードを作成しましょう!
今回はMonoBehaviour.GetComponent<T>()
というメソッドを使用しています。このメソッドはコンポーネントがアタッチされているGameObjectから指定した型(<T>
の部分)のコンポーネントを取得するものになります。
メソッドではありますがテンプレート引数を持つものになっており、C#のテンプレート(Template)という機能を利用したメソッドになっています(テンプレートに関しては他の記事で解説します)。
もし、指定した型のコンポーネントが取得できなかった場合はnull
という何も指していない参照値を返します。サンプルコードではif文を使ってnullチェックを行なっています。(nullについてはクラスと一緒に説明します。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using UnityEngine; public class Sample : MonoBehaviour { public string[] Texts; void Start() { //アタッチしているGameObjectからTextMeshコンポーネントを取得している。 var textMesh = GetComponent<TextMesh>(); if(textMesh == null) return; //なかったら、何もしない。 // Textsの内容をTextMeshのtextプロパティに設定していく。 // 下のコードだと一つのテキストのごとに改行される。 for(var i=0; i<Texts.Length; ++i) { textMesh.text += Texts[i]; textMesh.text += System.Environment.NewLine; //改行文字をつけている } } } |
サンプルコードのビルドに成功したら、テキストを表示するためのGameObjectを作成しましょう!
(注:System.Environment.NewLine; は”\r\n”の意味。OSごとの環境要因にとらわれずに改行できるためC#コードでしばしば使われる。)
GameObjectメニューの3D Objects > 3D Textを押して、シーン上にTextMeshコンポーネントがアタッチされたGameObjectを作成しましょう!(HierarchyタブとメニューのGameObjectのどちらからでもOKです。)
作成してすぐの状態だと微妙に見づらいので、Transformのスケールを変更したり、TextMeshのFontSizeやAnchorを調節してみてください。
作成したら、サンプルコードのスクリプトをGameObjectにアタッチ。Inspectorから表示したいテキストをTextsに入力してください。
入力が終わりましたら、再生ボタンを押してみてください。問題なければ画面に入力したテキストが表示されます。
まとめ
今回の記事ではstring型について学びました。コンピュータでは直接テキストを表すことができないので色々な工夫がなされています。
今回の記事の内容を以下にまとめます。
- string型は文字列を表す参照型。
- 文字用の配列になる。
- コンピュータ上では文字は文字コードという文字と数値の対応表を使って表現されている。
- C#ではUTF-16という文字コードを使用している。
- 改行文字などそのまま書けない文字はエスケープシーケンスを使って表現する。
- エスケープシーケンスは
\
で始まる2つ以上の文字を組み合わせたもの。 - 文字列は
"<文字>..."
と書く。 @"<文字>..."
はエスケープシーケンスを無視して文字列。$"<文字>..."
は{}
で値を文字列の中に埋め込むことができる文字列。- C#では文字列処理専用のメソッドが用意されている。
- 文字列用のメソッドは他プログラミング言語でも似たものがある。
- C#には文字列から数値型へ変換するメソッドも用意されている。
- その他の型はシリアライズと呼ばれる方法で相互変換することができる。
- string型の合成は処理の負荷が高い。
System.StringBuilder
を利用するとある程度緩和することができる。
それでは次の記事に行ってみましょう!
次回の記事:
コメント