前回は、Unity 6でSphereを取得アイテムとして配置し、Is TriggerとC#スクリプトを使って、PlayerがItemに触れるとItemが消える仕組みを作りました。
今回はその仕組みをさらに発展させます。
ゲームエリア内にItemを複数配置し、Playerが取得するたびに、
Score: 0
↓
Itemを1つ取得
↓
Score: 1
↓
さらにItemを取得
↓
Score: 2
のようにスコアが増える仕組みを作ります。
ゲーム画面へのスコア表示にはUnityのTextMeshProを使用します。
さらに今回もAIに相談しながらC#スクリプトを作成し、前回のItemPickupとスコア管理を連携させていきます。
前回のアイテム取得処理についてはこちらの記事で解説しています。
Unity 6でアイテムを取得する方法|Is TriggerとC#で触れたら消す仕組みを作る
- 今回作るもの
- Itemを管理するためのItemsを作成する
- Itemを複製して5個配置する
- TextMeshProでScoreTextを作成する
- ScoreTextを画面左上に配置する
- AIにスコア管理用のコードを質問する
- ScoreManagerスクリプトを作成する
- TMP_Textとは?
- score変数で取得数を保存する
- AddScoreでスコアを増やす
- ScoreTextを更新する
- ScoreManagerをPlayerへ追加する
- ItemPickupからScoreManagerを呼び出す
- GetComponentでScoreManagerを取得する
- nullを確認してからスコアを増やす
- 複製したItemにもItemPickupが付いているか確認する
- Playモードでスコアを確認する
- スコアが増えない場合
- TextMeshProを使うとゲームの情報を画面に表示できる
- Hierarchyを整理する
- 今回のまとめ
- 次回はすべてのアイテムを取得したらゲームクリアにする
今回作るもの
今回は前回作ったItemを複製し、ゲームエリア内に複数配置します。
さらに画面左上に、
Score: 0
というテキストを表示します。
PlayerがItemを取得すると、
Score: 1
Score: 2
Score: 3
のように数字が増えていくようにします。
今回の主な流れは、
- Itemを複数配置する
- Itemsという親GameObjectで整理する
- TextMeshProでScoreTextを作成する
- ScoreManagerスクリプトを作成する
- ScoreManagerをPlayerへ追加する
- ItemPickupからScoreManagerを呼び出す
- Item取得時にスコアを1増やす
- Playモードで動作確認する
となります。
Itemを管理するためのItemsを作成する
これまで壁はWalls、障害物はObstaclesという親GameObjectにまとめました。
今回も同じように、複数のItemをまとめるための空のGameObjectを作成します。
名前は、
Items
にします。
Transformは、
Position = X 0 / Y 0 / Z 0
Rotation = X 0 / Y 0 / Z 0
Scale = X 1 / Y 1 / Z 1
にしておきます。
前回作ったItemは、
Item_01
へ名前を変更し、Itemsの子GameObjectにします。
最終的には、
Items
├─ Item_01
├─ Item_02
├─ Item_03
├─ Item_04
└─ Item_05
という状態にします。
Itemを複製して5個配置する
前回作ったItemにはすでに、
- Sphere Collider
- Is Trigger
- ItemMaterial
- ItemPickup
が設定されています。
そのため、同じItemを複製すれば同じ設定をそのまま利用できます。
今回は5個のItemを配置します。
例えば次の位置にします。
Item_01
Position = X 3 / Y 0.75 / Z -2
Item_02
Position = X -3 / Y 0.75 / Z 1
Item_03
Position = X 6 / Y 0.75 / Z 6
Item_04
Position = X -7 / Y 0.75 / Z -4
Item_05
Position = X 0 / Y 0.75 / Z 7
Scaleはすべて、
X = 0.5
Y = 0.5
Z = 0.5
のままでOKです。
障害物と重なる場合はPositionを少し調整しても問題ありません。

ゲームエリア内のいろいろな場所にItemがあることで、Playerを移動させながら集められるようになります。
TextMeshProでScoreTextを作成する
次に、取得したItemの数をゲーム画面へ表示します。
今回はUnityの、
TextMeshPro
を使用します。
Hierarchyから、
UI → Text – TextMeshPro
を作成します。
初めてTextMeshProを使用する場合、
TMP Importer
などの画面が表示されることがあります。
その場合は、
Import TMP Essentials
を選択します。
TextMeshProのTextを作成すると、自動的にCanvasも作成されます。
作成したTextの名前は、
ScoreText
に変更します。
ScoreTextを画面左上に配置する
ScoreTextの表示内容を、
Score: 0
に変更します。
今回はゲーム中に見やすいように、画面左上へ配置します。
文字サイズは、
36
程度から始めると分かりやすいです。
文字が小さい、または大きすぎる場合はGameビューを確認しながら調整します。
最初は、
Score: 0
と表示されていればOKです。
この段階ではまだItemを取得しても数字は変わりません。
これからC#スクリプトでScoreTextを書き換えられるようにします。

AIにスコア管理用のコードを質問する
今回もC#コードをAIに相談して作成します。
例えばChatGPTへ次のように質問します。
Unity 6で3Dゲームを作っています。
PlayerがItemを取得するとスコアを1増やしたいです。
画面にはTextMeshProで「Score: 0」というScoreTextを作成しています。
PlayerにScoreManagerスクリプトを追加し、Itemを取得するたびにScoreを1増やしてScoreTextを更新したいです。
初心者向けのシンプルなC#コードを作ってください。

今回も、
TextMeshProを使用している
ScoreManagerをPlayerへ追加する
Item取得時に1増やす
という条件を具体的にAIへ伝えます。
ScoreManagerスクリプトを作成する
Assets → Scripts
フォルダに新しいC#スクリプトを作成します。
名前は、
ScoreManager
にします。
今回は次のコードを使用します。
using TMPro;
using UnityEngine;
public class ScoreManager : MonoBehaviour
{
[SerializeField] private TMP_Text scoreText;
private int score = 0;
private void Start()
{
UpdateScoreText();
}
public void AddScore(int amount)
{
score += amount;
UpdateScoreText();
}
private void UpdateScoreText()
{
scoreText.text = $"Score: {score}";
}
}

保存したらUnityへ戻り、Consoleにエラーが表示されていないことを確認します。
TMP_Textとは?
今回のコードでは、
[SerializeField] private TMP_Text scoreText;
を使用しています。
TMP_TextはTextMeshProのテキストをC#スクリプトから操作するために使用します。
コードの最初に、
using TMPro;
があるのもそのためです。
[SerializeField]を付けているため、UnityのInspectorからScoreTextを設定できるようになります。
score変数で取得数を保存する
次に、
private int score = 0;
があります。
ここに現在のスコアを保存します。
ゲーム開始時は、
0
からスタートします。
Itemを取得するたびに、この数字を増やしていきます。
AddScoreでスコアを増やす
スコアを増やすために、
public void AddScore(int amount)
{
score += amount;
UpdateScoreText();
}
という処理を作っています。
例えば、
AddScore(1);
を実行すると、現在のScoreへ1が追加されます。
Scoreが0の場合、
0 + 1 = 1
となります。
さらにもう1つ取得すると、
1 + 1 = 2
となります。
ScoreTextを更新する
スコアが変わったら、
private void UpdateScoreText()
{
scoreText.text = $"Score: {score}";
}
を実行します。
例えばscoreが3の場合、
Score: 3
と画面に表示されます。
スコアの数字そのものと、ゲーム画面に表示される文字をこのメソッドで連動させています。
ScoreManagerをPlayerへ追加する
作成したScoreManagerスクリプトをPlayerへ追加します。
Hierarchyで、
Player
を選択します。
Inspectorの、
Add Component
からScoreManagerを追加します。
するとScoreManagerの中に、
Score Text
という項目が表示されます。
ここにはHierarchyの、
ScoreText
をドラッグして設定します。
これでScoreManagerからScoreTextを変更できるようになります。

ItemPickupからScoreManagerを呼び出す
現在のItemPickupでは、PlayerがItemに触れるとItemを削除するだけです。
今回はその前にスコアを増やします。
ItemPickup.csを次のように修正します。
using UnityEngine;
public class ItemPickup : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
ScoreManager scoreManager = other.GetComponent<ScoreManager>();
if (scoreManager != null)
{
scoreManager.AddScore(1);
}
Debug.Log("Item collected!");
Destroy(gameObject);
}
}
}

これでItemへPlayerが触れると、Playerに付いているScoreManagerを探します。
ScoreManagerが見つかった場合、
scoreManager.AddScore(1);
が実行されます。
そのあとItemを削除します。
GetComponentでScoreManagerを取得する
今回新しく登場したのが、
other.GetComponent<ScoreManager>();
です。
otherにはItemへ触れたGameObjectのColliderが入っています。
今回はPlayerが触れるため、PlayerからScoreManagerを探しています。
PlayerにScoreManagerが付いていれば、そのComponentを取得できます。
そのため今回の設定では、ScoreManagerを別のGameObjectではなくPlayerへ追加しています。
nullを確認してからスコアを増やす
コードでは、
if (scoreManager != null)
という確認も行っています。
これは、
ScoreManagerが本当に見つかったか
を確認する処理です。
ScoreManagerが見つかった場合だけ、
scoreManager.AddScore(1);
を実行します。
こうすることで、ScoreManagerが設定されていない状態で処理を実行してエラーになる可能性を減らせます。
複製したItemにもItemPickupが付いているか確認する
前回のItemを複製して作った場合は、通常ItemPickupも一緒に複製されています。
Hierarchyで、
Item_01
Item_02
Item_03
Item_04
Item_05
を確認します。
それぞれに、
Item Pickup (Script)
が付いていることを確認してください。
また、Sphere Colliderの、
Is Trigger
もONになっていることを確認します。
Playモードでスコアを確認する
すべて設定できたらPlayボタンを押します。
ゲーム開始時には、
Score: 0
と表示されます。
PlayerをW・A・S・Dキーで操作してItemを1つ取得します。
Itemが消えて、
Score: 1
になれば成功です。
さらに別のItemを取得します。
Score: 2
Score: 3
と増えていくことを確認します。

5個すべて取得した場合は、
Score: 5
になります。
これでPlayerが取得したItemの数をゲーム画面から確認できるようになりました。

スコアが増えない場合
Itemは消えるのにScoreが増えない場合は、まずPlayerを選択します。
ScoreManager
が追加されているか確認してください。
さらにScoreManagerの、
Score Text
にHierarchyのScoreTextが設定されているか確認します。
また、
ItemPickup.cs
が新しいコードになっていることも確認してください。
Itemそのものが消えない場合は、
- PlayerのTagが
Playerになっているか - Itemの
Is TriggerがONか - Itemに
ItemPickupが付いているか - Consoleに赤いエラーがないか
を確認します。
TextMeshProを使うとゲームの情報を画面に表示できる
今回はTextMeshProを使ってスコアを表示しました。
ゲームではスコア以外にも、
残り時間
HP
所持金
アイテム数
ステージ名
ゲームクリアのメッセージ
など、多くの情報をUIとして画面に表示します。
今回作ったScoreTextは、その基本となる仕組みです。
今後ゲームの機能が増えたときにもTextMeshProを利用してさまざまな情報を表示できます。
Hierarchyを整理する
ここまで進めるとHierarchyは例えば、
Main Camera
Directional Light
Ground
Player
Walls
├─ Wall_North
├─ Wall_South
├─ Wall_East
└─ Wall_West
Obstacles
├─ Obstacle_01
├─ Obstacle_02
└─ Obstacle_03
Items
├─ Item_01
├─ Item_02
├─ Item_03
├─ Item_04
└─ Item_05
Canvas
└─ ScoreText
EventSystem
のようになります。
ゲーム制作が進むにつれてGameObjectも増えてきました。
Walls
Obstacles
Items
のように種類ごとに整理しておくことで、後から必要なGameObjectを見つけやすくなります。
今回のまとめ
今回はUnity 6で複数のItemを配置し、取得した数をスコアとして画面に表示する仕組みを作りました。
TextMeshProを使って、
Score: 0
というUIを作成しました。
さらにScoreManagerスクリプトをPlayerへ追加し、Itemを取得するたびにスコアを1増やします。
ItemPickupからGetComponent<ScoreManager>()を使ってPlayerのScoreManagerを取得し、
scoreManager.AddScore(1);
を実行することで、Item取得とスコア表示を連携させました。
前回は「Itemに触れたら消える」だけでしたが、今回はPlayerの行動を数字としてゲーム画面へ反映できるようになりました。
少しずつゲームとして必要な仕組みが増えてきています。
次回はすべてのアイテムを取得したらゲームクリアにする
今回は5つのItemを取得すると、
Score: 5
まで増える仕組みを作りました。
次回は、このスコアを利用して、
Itemをすべて取得する
↓
Scoreが5になる
↓
GAME CLEAR!を表示する
という仕組みを作ります。
TextMeshProを使ってクリアメッセージを表示し、ゲームの「目的」と「終了条件」を追加していきます。

