ボクステ公式ブログ

[Unity]string(文字列)の中に複数の変数を代入する方法[$"{}"][Replace]
Unity6.2(Ver.6000.2.7f2)でのスクリプトを想定しているため、以下の記述例は
C# です。
<用語>
変数 … 値を入れる箱のようなもの。
変数の型 … 変数に入れることができる値の種類。
string型 … 値が文字列の変数。
int型 … 値が整数の変数。
bool型 … 値がtrue(真)かfalse(偽)の変数。
<変数の例>
文字列はダブルクォーテーションで囲みます。
name="Takashi"; にすると、nameの中身が Alice から Takashi に変わります。 すでにnameの型はstringであると宣言しているので、以降は先頭にstringはつけず name="Ken"; と書いて良いです。
age=25; にすると、ageの中身が18から25に変わります。
<変数の代入>
次の文章テンプレートがあるとします。
「私の名前は〇〇で、年齢は△△歳です。」
〇〇にname、△△にageを入れる場合には次のような方法があります。
+ で繋ぐ方式
これは、"固定の文字列"+変数+"固定の文字列". のようにstring型の文章を繋ぐ形式で、変数が多くなると読みにくくなります。
実際に、Unity上でデバッグログとして表示する際には、以下のC#スクリプトを作ってヒエラルキーの空いたところにドラッグ&ドロップするか、空のオブジェクトを作ってそのインスペクターにドラッグ&ドロップしてからゲームを再生してください。

代入後に表示される文章例は「My name is Alice and I am 18 years old.」となります。
なお、これはstring型全般の特徴ですが、変数名として代入する時は、ダブルクォーテーションが不要です。
$"{ }" 方式
先頭に$をつけ、変数を{ }で囲むことにより、変数を文字列の中に直接代入できます。
+方式の時は、 " and I am "、" years old." のように" "で括った文字列の前後に変数が入った完成形を考慮して半角スペースを入れなくてはなりません。
一方、 $"{ }" 方式では、見かけ通りスペースを取れるため簡単です。
もし変数名の周りに{}をつけなかった場合、そのまま「name」という文字列として表示され、変数として働きません。
コンソールのデバッグログでキャラクターの名前を表示したい場合などは、
bool型でも同様に
Replace方式
上記の方法でも困るのがゲーム内での翻訳時です。
ゲーム内には、player_nameやnpc_name、enemy_nameなど複数の名前用変数が混在しがちです。
翻訳テンプレート内に{player_name}と書いた場合、呼び出し側のスクリプト内に string player_name;という変数があれば、その中身(例:"Alice","Takashi"など)が代入されます。
しかし、 npc_nameを入れたい時でもplayer_nameしか呼び出せません。
共通のテンプレートを使いまわして、異なる変数を代入する時に使えるのがRepcalce(置き換え)です。
bool型のisPlayerがtrue(プレイヤーである)時は、{name}にplayer_name、{age}にplayer_ageを代入し、それ以外の場合は、{name}にnpc_name、{age}にnpc_ageを代入しています。
このように、代入する変数が異なっても同じテンプレートで対応できます。

isPlayerがfalseの時の表示。プレイヤーのAliceではなくNPCのTom情報になっている。
Replaceと$"{}"の併用
文字列の一部に特定の色を付けるなど装飾したい時も文章テンプレート内にコードを書くのは煩雑ですし、後で文字色を変更したい時にテンプレート内のカラーコードを全て書き換えることになります。
Unityの文字は、TextMeshProを使うと、<color=#FF0000>赤文字</color>のように、特定の部分だけ色を変える ことができます。
Unityプロジェクトのヒエラルキー(デフォルトでは画面左端)の領域で右クリックし、UI>Text TextMeshPro を選択するとCanvasとその子としてのText用オブジェクトが作成されます。
ヒエラルキー欄
YourProject
|_Canvas
|_Text(TMP)

部分解説
このマークアップ言語方式は、Webサイトを作る時のHTMLとよく似ています。
player_name つまり現在だと Alice の前後にカラータグを入れた次の文字列を作っています。
<color=#FF0000>Alice</color>
これをTextMeshProのテキストウィンドウに入れると、Aliceと色付きで表示されます。

Unity内でゲームを実行時、TextMeshProのTextウィンドウにカラータグ付き文字列が生成されている。
結果(result)部分を抜粋すると次の通りです。
同様に、
繋げると、以下の表示となります。
英語 My name is Alice and I am 18 years old.
日本語 私の名前は、Alice です。年齢は 18 歳です。
※緑文字は白が背景だと視認性が悪いため黒背景にしていますがC#のコードには背景色変更コードが含まれません。
以上のように、Replace方式の中に$"{}"方式を含み2重代入することで、変数内の変化と文字色の変化を同時に編集できます。
これは、ゲームログやシステムメッセージに利用できで、npcやplayerの名前、獲得したアイテム名・個数などを色分けして見やすくできます。
当ブログに掲載されたコードはコピーペースト自由です。権利表記も要りません。無料の趣味でも有料の仕事用コードでも、お好きなようにお使いください。
※上記のままでは同じテキスト内容と文字色しか表示されませんので、変数名や型、値を改造しておつかい下さい。
カテゴリ ゲーム開発
C# です。
<用語>
変数 … 値を入れる箱のようなもの。
変数の型 … 変数に入れることができる値の種類。
string型 … 値が文字列の変数。
int型 … 値が整数の変数。
bool型 … 値がtrue(真)かfalse(偽)の変数。
<変数の例>
Sample.cs(C#)
string name = "Alice";
この場合、name(名前)というstring型の変数に Alice という文字列が入っています。文字列はダブルクォーテーションで囲みます。
name="Takashi"; にすると、nameの中身が Alice から Takashi に変わります。 すでにnameの型はstringであると宣言しているので、以降は先頭にstringはつけず name="Ken"; と書いて良いです。
Sample.cs(C#)
int age=18;
この場合、age(年齢)というint型の変数に18という整数が入っています。age=25; にすると、ageの中身が18から25に変わります。
<変数の代入>
次の文章テンプレートがあるとします。
「私の名前は〇〇で、年齢は△△歳です。」
〇〇にname、△△にageを入れる場合には次のような方法があります。
+ で繋ぐ方式
Sample.cs(C#)
string template = "My name is "+ name + " and I am "+ age + " years old.";
これは、"固定の文字列"+変数+"固定の文字列". のようにstring型の文章を繋ぐ形式で、変数が多くなると読みにくくなります。
実際に、Unity上でデバッグログとして表示する際には、以下のC#スクリプトを作ってヒエラルキーの空いたところにドラッグ&ドロップするか、空のオブジェクトを作ってそのインスペクターにドラッグ&ドロップしてからゲームを再生してください。
Sample.cs(C#)
using UnityEngine;
public class Sample : MonoBehaviour
{
string name = "Alice";
int age = 18;
void Start()
{
string template = "My name is "+ name + " and I am "+ age + " years old.";
Debug.Log(template);
}
}
public class Sample : MonoBehaviour
{
string name = "Alice";
int age = 18;
void Start()
{
string template = "My name is "+ name + " and I am "+ age + " years old.";
Debug.Log(template);
}
}

代入後に表示される文章例は「My name is Alice and I am 18 years old.」となります。
なお、これはstring型全般の特徴ですが、変数名として代入する時は、ダブルクォーテーションが不要です。
$"{ }" 方式
Sample.cs(C#)
string template= $"My name is {name} and I am {age} years old.";
この方法は、変数が多くなっても見やすいのが特徴です。先頭に$をつけ、変数を{ }で囲むことにより、変数を文字列の中に直接代入できます。
+方式の時は、 " and I am "、" years old." のように" "で括った文字列の前後に変数が入った完成形を考慮して半角スペースを入れなくてはなりません。
一方、 $"{ }" 方式では、見かけ通りスペースを取れるため簡単です。
もし変数名の周りに{}をつけなかった場合、そのまま「name」という文字列として表示され、変数として働きません。
コンソールのデバッグログでキャラクターの名前を表示したい場合などは、
Sample.cs(C#)
Debug.Log($"name: {name}");
と記述すれば、「name:Alice」というように、 {}で囲んだ方のnameだけ、変数の中身が表示されるので見出しラベルとの使い分けができます。bool型でも同様に
Sample.cs(C#)
bool isPlayer=ture;//プレイヤーかどうか
Debug.Log($"isPlayer: {isPlayer}");
と記述することにより、「isPlayer:true」と、{}で囲んだ方だけ変数の中身が表示されます。Debug.Log($"isPlayer: {isPlayer}");
Replace方式
上記の方法でも困るのがゲーム内での翻訳時です。
ゲーム内には、player_nameやnpc_name、enemy_nameなど複数の名前用変数が混在しがちです。
翻訳テンプレート内に{player_name}と書いた場合、呼び出し側のスクリプト内に string player_name;という変数があれば、その中身(例:"Alice","Takashi"など)が代入されます。
しかし、 npc_nameを入れたい時でもplayer_nameしか呼び出せません。
共通のテンプレートを使いまわして、異なる変数を代入する時に使えるのがRepcalce(置き換え)です。
Sample.cs(C#)
using UnityEngine;
public class Sample : MonoBehaviour
{
string player_name="Alice";
string npc_name="Tom";
int player_age=18;
int npc_age=30;
bool isPlayer=false;//プレイヤーならtrue,それ以外ならfalse
string template = "";
string language = "en";//言語選択は他でしているものとします
private void Start()
{
switch (language)
{
case "en"://英語の時
template = "My name is {name} and I am {age} years old.";
//$を付けず、変数ではなくStringの一部として扱います
break;
case "ja"://日本語の時
template = "私の名前は、{name} です。年齢は {age} 歳です。";
//同じく$を付けず、単なるStringとして扱います
break;
default:
template = "My name is {name} and I am {age} years old.";
break;
}
if (isPlayer) //if (isPlayer==true)と同じ意味:プレイヤーの時は
{
string result = template.Replace("{name}", player_name).Replace("{age}", player_age.ToString());
Debug.Log(result);
}
else //上記以外の全ての場合(つまりプレイヤーではない時)
{
string result = template.Replace("{name}", npc_name).Replace("{age}", npc_age.ToString());
Debug.Log(result);
}
//player_age.ToString() では、int型であるplayer_age = 18 を string型の"18"に変換しています。
}
}
Replaceの中で、{name} をさらにダブルクォーテーションで囲み "{name}" としているのは、テンプレート内の {name} の部分を一つの文字列とみなし、変数 player_name の中身 Alice と置き換えるためです。public class Sample : MonoBehaviour
{
string player_name="Alice";
string npc_name="Tom";
int player_age=18;
int npc_age=30;
bool isPlayer=false;//プレイヤーならtrue,それ以外ならfalse
string template = "";
string language = "en";//言語選択は他でしているものとします
private void Start()
{
switch (language)
{
case "en"://英語の時
template = "My name is {name} and I am {age} years old.";
//$を付けず、変数ではなくStringの一部として扱います
break;
case "ja"://日本語の時
template = "私の名前は、{name} です。年齢は {age} 歳です。";
//同じく$を付けず、単なるStringとして扱います
break;
default:
template = "My name is {name} and I am {age} years old.";
break;
}
if (isPlayer) //if (isPlayer==true)と同じ意味:プレイヤーの時は
{
string result = template.Replace("{name}", player_name).Replace("{age}", player_age.ToString());
Debug.Log(result);
}
else //上記以外の全ての場合(つまりプレイヤーではない時)
{
string result = template.Replace("{name}", npc_name).Replace("{age}", npc_age.ToString());
Debug.Log(result);
}
//player_age.ToString() では、int型であるplayer_age = 18 を string型の"18"に変換しています。
}
}
bool型のisPlayerがtrue(プレイヤーである)時は、{name}にplayer_name、{age}にplayer_ageを代入し、それ以外の場合は、{name}にnpc_name、{age}にnpc_ageを代入しています。
このように、代入する変数が異なっても同じテンプレートで対応できます。

isPlayerがfalseの時の表示。プレイヤーのAliceではなくNPCのTom情報になっている。
Replaceと$"{}"の併用
文字列の一部に特定の色を付けるなど装飾したい時も文章テンプレート内にコードを書くのは煩雑ですし、後で文字色を変更したい時にテンプレート内のカラーコードを全て書き換えることになります。
Unityの文字は、TextMeshProを使うと、<color=#FF0000>赤文字</color>のように、
Unityプロジェクトのヒエラルキー(デフォルトでは画面左端)の領域で右クリックし、UI>Text TextMeshPro を選択するとCanvasとその子としてのText用オブジェクトが作成されます。
ヒエラルキー欄
YourProject
|_Canvas
|_Text(TMP)
Sample.cs(C#)
using UnityEngine;
using TMPro; //TextMeshProを使うための宣言
public class Sample : MonoBehaviour
{
public TextMeshProUGUI text_Dialogue;
//↑TextMeshPro要素を持つオブジェクトをインスペクターにアタッチ(ドラッグ&ドロップ)
string player_name="Alice";
int player_age =18;
string template = "";
string language = "en"; //現在の言語
void Start()
{
string coloredName = ColorWrap(player_name,"#FF0000"); //赤
string coloredAge = ColorWrap(player_age.ToString(),"#00FF00");//緑
string ColorWrap(string text, string hex)
=> $"<color={hex}>{text}</color>";
//[悪い例] color = {hex} のように=の前後にスペースが空いているとTextMeshProのフィールドでタグと見なされないので隙間を作らない
switch (language)
{
case "en": //英語の時
template = "My name is {name} and I am {age} years old.";
//$を付けず、変数ではなくStringの一部として扱います
break;
case "ja": //日本語の時
template = "私の名前は、{name} です。年齢は {age} 歳です。";
//同じく$を付けず、単なるStringとして扱います
break;
default:
template = "My name is {name} and I am {age} years old.";
break;
}
string result = template.Replace("{name}",coloredName).Replace("{age}", coloredAge);
text_Dialogue.text=result;
//TextMeshPro要素を持つオブジェクトのテキストに、作った結果を入れます
}
}
上記コードをUnityのヒエラルキーに置き、インスペクター(通常画面右端パネル)内のText_Dialogue欄に先ほど作成したTextMeshPro要素を持つゲームオブジェクトをドラッグ&ドロップしてアタッチすることにより、結果(result)の文字列がゲーム内にテキスト表示されます。using TMPro; //TextMeshProを使うための宣言
public class Sample : MonoBehaviour
{
public TextMeshProUGUI text_Dialogue;
//↑TextMeshPro要素を持つオブジェクトをインスペクターにアタッチ(ドラッグ&ドロップ)
string player_name="Alice";
int player_age =18;
string template = "";
string language = "en"; //現在の言語
void Start()
{
string coloredName = ColorWrap(player_name,"#FF0000"); //赤
string coloredAge = ColorWrap(player_age.ToString(),"#00FF00");//緑
string ColorWrap(string text, string hex)
=> $"<color={hex}>{text}</color>";
//[悪い例] color = {hex} のように=の前後にスペースが空いているとTextMeshProのフィールドでタグと見なされないので隙間を作らない
switch (language)
{
case "en": //英語の時
template = "My name is {name} and I am {age} years old.";
//$を付けず、変数ではなくStringの一部として扱います
break;
case "ja": //日本語の時
template = "私の名前は、{name} です。年齢は {age} 歳です。";
//同じく$を付けず、単なるStringとして扱います
break;
default:
template = "My name is {name} and I am {age} years old.";
break;
}
string result = template.Replace("{name}",coloredName).Replace("{age}", coloredAge);
text_Dialogue.text=result;
//TextMeshPro要素を持つオブジェクトのテキストに、作った結果を入れます
}
}

部分解説
string ColorWrap(string text, string hex)
=> $"<color={hex}>{text}</color>";
ColorWrap に、text(文字列)と hex(16進数のカラーコード)を渡すと、TextMeshPro用のカラータグでstring型を囲みます。=> $"<color={hex}>{text}</color>";
このマークアップ言語方式は、Webサイトを作る時のHTMLとよく似ています。
string coloredName = ColorWrap(player_name,"#FF0000"); //赤
"#FF0000" とダブルクォーテーションで囲っているのは、単なる文字列としてタグの内部へ代入するためです。player_name つまり現在だと Alice の前後にカラータグを入れた次の文字列を作っています。
<color=#FF0000>Alice</color>
これをTextMeshProのテキストウィンドウに入れると、Aliceと色付きで表示されます。

Unity内でゲームを実行時、TextMeshProのTextウィンドウにカラータグ付き文字列が生成されている。
結果(result)部分を抜粋すると次の通りです。
string result = template.Replace("{name}",coloredName)
テンプレート内の文字列 {name} を、coloerName つまり、赤い色 かつ 変数 player_name の中身に置き換える という命令となります。同様に、
string result = template. /*中略*/.Replace("{age}", coloredAge);
では {age}部分を、coloredName つまり、カラーコード #00FF00(緑)かつ 変数 player_age の中身 に置き換えています。繋げると、以下の表示となります。
英語 My name is Alice and I am 18 years old.
日本語 私の名前は、Alice です。年齢は 18 歳です。
※緑文字は白が背景だと視認性が悪いため黒背景にしていますがC#のコードには背景色変更コードが含まれません。
以上のように、Replace方式の中に$"{}"方式を含み2重代入することで、変数内の変化と文字色の変化を同時に編集できます。
これは、ゲームログやシステムメッセージに利用できで、npcやplayerの名前、獲得したアイテム名・個数などを色分けして見やすくできます。
当ブログに掲載されたコードはコピーペースト自由です。権利表記も要りません。無料の趣味でも有料の仕事用コードでも、お好きなようにお使いください。
※上記のままでは同じテキスト内容と文字色しか表示されませんので、変数名や型、値を改造しておつかい下さい。
カテゴリ ゲーム開発
