【Unity入門】Statusコンポーネントを作って、GameObjectにHPを持たせよう
ゲームを作っていると、「プレイヤーにHPを持たせたい」「敵にも体力を持たせたい」という場面が必ず出てきます。
Unityでは、こうした「性質」を コンポーネント として作り、GameObjectにアタッチすることで持たせます。この記事では、HPを持つ Status コンポーネントを作りながら、Unityらしい考え方を体験していきます。

1. Statusスクリプトを作る
Projectウィンドウで C# スクリプトを作成し、名前を Status にします。中身は次のとおりです。
using UnityEngine;
public class Status : MonoBehaviour
{
public int Hp = 100;
}
ポイントは3つです。
MonoBehaviourを継承しているので、GameObjectにアタッチできるpublicを付けたので、Inspectorに表示され、数値を変更できる= 100は初期値
ファイル名とクラス名は必ず同じにしてください。違うとアタッチできません。
2. Playerにアタッチする
- Hierarchyで
PlayerというGameObjectを用意する(2Dスプライトでも、3Dの立方体でもかまいません) - 作成した
Statusスクリプトを、Inspectorにドラッグ&ドロップする - Inspectorに
Statusコンポーネントが追加され、Hpの欄に100と表示される
これで、PlayerはHPを持つGameObjectになりました。Inspectorで数値を書き換えれば、ゲームを動かさなくてもHPを調整できます。
3. 「Statusを付けるとHPを持てる」のがコンポーネント
このとき、Playerの中身はこうなっています。
Player
├ Transform
├ SpriteRenderer
├ Rigidbody2D
└ Status
└ Hp = 100
ここで大切なのは、HPをPlayerクラスそのものに埋め込んでいない ことです。
- 見た目を出すのは
SpriteRenderer - 物理的な動きは
Rigidbody2D - HPなどの数値は
Status
というように、役割ごとに部品(コンポーネント)を組み合わせてGameObjectを作ります。「あの部品を付ければ、あの機能が使える」という考え方が、Unityの基本です。
4. Statusを増やしてみよう
HPだけでなく、攻撃力や防御力も持たせてみましょう。
using UnityEngine;
public class Status : MonoBehaviour
{
public int Hp = 100;
public int Attack = 10;
public int Defense = 5;
}

こうしておくと、PlayerにもEnemyにも同じ Status を付けるだけで、同じ仕組みを持たせられます。
| GameObject | Hp | Attack | Defense |
|---|---|---|---|
| Player | 100 | 10 | 5 |
| Enemy | 30 | 8 | 2 |
スクリプトは1つだけ。数値はGameObjectごとにInspectorで変えられます。「クラスを増やさなくても、部品の組み合わせと設定値でキャラクターを作り分けられる」ことが体感できます。
5. スクリプトからStatusを追加する(AddComponent)
ここまではInspectorで操作しましたが、スクリプトから同じことをする方法もあります。
using UnityEngine;
public class PlayerCreator : MonoBehaviour
{
void Start()
{
GameObject obj = new GameObject("Player");
Status status = obj.AddComponent<Status>();
status.Hp = 100;
Debug.Log(obj.name + "のHP:" + status.Hp);
}
}
new GameObject("Player")で、空のGameObjectを作るAddComponent<Status>()で、Statusコンポーネントを追加する。戻り値は追加されたStatusなので、変数に受け取れるstatus.Hp = 100;で、外からHPの値を設定する
Inspectorでドラッグ&ドロップしていた操作が、「AddComponent を呼ぶ」というコードに対応していると分かります。
6. publicのままで大丈夫?
public int Hp は手軽ですが、実は どのスクリプトからでも自由に書き換えられる という弱点があります。
// どこかのスクリプトで、うっかり書いてしまった例
status.Hp = -9999;
HPがマイナスになったり、意図せず全回復したりするバグの原因になります。そこで、次のように書き換えます。
using UnityEngine;
public class Status : MonoBehaviour
{
[SerializeField]
private int hp = 100;
public int Hp => hp;
public void TakeDamage(int damage)
{
hp -= damage;
if (hp < 0)
{
hp = 0;
}
}
}
[SerializeField]を付けると、privateでもInspectorに表示され、数値を設定できるprivateなので、外のスクリプトから直接書き換えられないpublic int Hp => hp;は「読み取り専用」の窓口。外からはHPを読めるが、書き換えはできない- HPを減らすときは
TakeDamageを呼ぶ。0未満にならないよう、Status自身が守る
使う側は次のようになります。
Status status = GetComponent<Status>();
status.TakeDamage(20);
Debug.Log(status.Hp); // 80
注意点として、private にしたあとは、5章の status.Hp = 100; のような書き方はできなくなります(読み取り専用のため、エラーになります)。初期値を変えたいときは、Inspectorで設定するか、必要に応じて設定用のメソッドを用意します。
7. まとめ
Statusのような自作コンポーネントを作り、アタッチすることで、GameObjectに性質を持たせられる- まずは
public int Hpで、「Inspectorに出して数値を変えられる」ことを体験する - 同じ
StatusをPlayerにもEnemyにも付けて使い回せる AddComponent<Status>()で、スクリプトからもコンポーネントを追加できる- 慣れてきたら
[SerializeField] privateとTakeDamageのようなメソッドで、安全に値を守る
「何でも1つのクラスに詰め込む」のではなく、「部品を組み合わせる」という感覚を、ぜひ身につけてください。
練習問題
StatusにMpを追加し、Inspectorに表示されることを確認してみましょう- Enemyを作り、
Hp = 30のStatusを付けてみましょう Statusに回復用のHeal(int amount)メソッドを追加してみましょう。ただし、最大HPを超えないようにしてください(ヒント:maxHpを別に用意します)- キーを押したらPlayerの
TakeDamage(10)が呼ばれるスクリプトを書き、ConsoleでHPの減り方を確認しましょう









ディスカッション
コメント一覧
まだ、コメントがありません