WinFormsのButtonからUnityのGameObjectへ ― newとComponentの違いを比べてみよう
前回の記事では、デザイナーが自動生成していた new Button() や Click += を、自分で書いてみました。
Unityでも画面に「もの」を置いて動かしますが、作り方の考え方が少し違います。WinFormsでは完成した部品を作って追加しました。Unityでは土台に機能を組み合わせて作ります。
この記事では、その違いを「ボタン」という同じ題材で比べてみます。

この記事の位置づけ
- GitHub Desktopで見てみよう ― WinFormsでボタンを置くと、裏では何が変わる?
- WinFormsで学ぶインスタンス ― Designerが書いたコードを自分で書いてみよう
- この記事:WinFormsの部品の作り方が、Unityではどう変わるかを整理する
この記事は「WinFormsからUnityへ ― C#で学んだことをUnityにつなげる学習ルート」のSTEP 3(橋3)にあたります。
1. WinFormsのおさらい ― 完成した部品を作って追加する
前回書いたコードを思い出しましょう。
Button button = new Button(); // ボタンを作る
button.Text = "押して"; // 文字を設定する
button.Click += Button_Click; // クリックされたときの処理を登録する
Controls.Add(button); // フォームに追加する
Button クラスには、ボタンに必要な機能が最初から全部入っています。
- 画面に表示される
- 文字を持っている(
Text) - 位置と大きさを持っている(
Location、Size) - クリックできる(
Click)
つまりWinFormsでは、「機能がそろった完成品」を new で作り、フォームに追加するという流れです。
2. Unityのボタンを分解してみよう
Unityでもボタンを作ってみます。
Hierarchyの「+」から UI > Button – TextMeshPro を選びます。(初回は TextMeshPro のインポート画面が出るので、「Import TMP Essentials」を押します。)
作られた「Button」を選択して、Inspectorを見てください。

UnityのButtonは、1つの完成品ではありません。「Button」という名前のGameObjectに、4つのComponentが付いたものです。
さらにHierarchyでButtonの左の▶を開くと、子として「Text (TMP)」があります。
WinFormsでは button.Text というプロパティでした。Unityでは、文字は別のGameObjectとして、ボタンの子に置かれています。

実験:Componentを無効にしてみよう
Inspectorで、Image や Button Componentを一時的に無効にして、Gameビューで変化を確かめてみましょう。Component名の左にあるチェックボックスを外すと、そのComponentが無効になります。(Rect Transform のように、チェックボックスがないComponentもあります。)
- Image を無効にする → 背景が消え、文字だけが残る
- Button を無効にする → 見た目はそのままでも、押しても反応しない
確かめたら、チェックを元に戻しておきましょう。
「見た目」と「押せる機能」が、別々の部品になっていることが分かります。
3. 考え方の違い
| 比べる点 | WinForms | Unity |
|---|---|---|
| 部品の正体 | Button という完成品 | GameObject + 複数のComponent |
| 機能の持たせ方 | クラスに最初から入っている | Componentを追加する |
| 文字 | Text プロパティ | 子のGameObject(TextMeshPro) |
| 機能の分かれ方 | Button クラスにまとまっている | 複数のComponentに分かれている |
ここで大切なのは、「Button → GameObject」と単純に置き換えて覚えないことです。
GameObjectそのものは、機能を入れておく「土台」のような存在です。GameObjectを作ると、位置・回転・大きさを表す Transform Componentが必ず付きます。そこに必要なComponentを追加することで、「表示する」「当たり判定を持つ」「物理的に動く」といった機能を持たせていきます。
GameObjectは土台で、「何ができるか」はComponentで決まる。
これがUnityの基本の考え方です。
4. 3Dオブジェクトでも同じ
ボタン以外でも確かめてみましょう。Hierarchyの「+」から 3D Object > Cube を作ります。

Cubeも「立方体」という完成品ではなく、Componentの組み合わせでできています。
ここで Inspector の Add Component から Rigidbody を追加して、再生してみてください。Cubeが落ちていきます。
Componentを1つ足しただけで、「重力で落ちる」という機能が増えました。これが、Unityで「できること」を作っていく方法です。
5. コードで比べてみよう
今度は、「オブジェクトを作って機能を持たせる」という流れを、Unityのコードでも見てみましょう。
using UnityEngine;
public class CubeMaker : MonoBehaviour
{
void Start()
{
// 土台と基本のComponentを作る
// (Transform・Mesh Filter・Mesh Renderer・Box Colliderが付く)
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.name = "FallingCube";
cube.transform.position = new Vector3(0, 3, 0);
// 機能を追加する
cube.AddComponent<Rigidbody>();
}
}
空のGameObjectにこのスクリプトを付けて再生すると、Cubeが作られて落ちていきます。
同じものを対応させるのではなく、作り方の流れを比べると、次のようになります。

ボタンのクリックはどうなる?
WinFormsの Click += にあたるものも、Unityのボタンにあります。
using UnityEngine;
using UnityEngine.UI;
public class ButtonTest : MonoBehaviour
{
[SerializeField] private Button button;
void Start()
{
button.onClick.AddListener(OnButtonClick); // WinFormsの Click += にあたる
}
private void OnButtonClick()
{
Debug.Log("押されました");
}
}
ここで button の型になっている Button は、GameObjectではなく、GameObjectに付いている「Button」Componentのことです。クリックの機能はComponentが持っているので、そこに処理を登録します。
(クリック時の処理は、InspectorのButtonの「On Click ()」欄から登録することもできます。)
6. なぜ new PlayerController() と書かないのか
GameObjectは new GameObject() で作れます。では、自分で作ったスクリプトはどうでしょうか。
PlayerController pc = new PlayerController(); // ✕ これはしない
Unityで自分が作るスクリプト(MonoBehaviour を継承したクラス)も、Componentの一種です。Componentは必ずどれかのGameObjectに付いている必要があり、単独では存在できません。
そのため、new で作るのではなく、「このGameObjectに付けてください」とUnityに頼みます。
player.AddComponent<PlayerController>(); // ○ コードで付ける
Inspectorでスクリプトをドラッグ&ドロップしたり、Add Componentで追加したりする操作は、これと同じことを画面から行っているのです。
実際に new で作ろうとすると、Unityはコンソールに警告を出します。
7. 画面とファイルの対応
前回、GitHub Desktopで「デザイナーでボタンを置くと Form1.Designer.cs が変わる」ことを確認しました。Unityでも同じように対応させることができます。
| WinForms | Unity |
|---|---|
| フォームデザイナー | Sceneビュー |
| プロパティウィンドウ | Inspector |
| Formの中のControl(親子関係) | Hierarchy(親子関係) |
Form1.Designer.cs | シーンファイル(.unity) |
UnityでComponentを追加してシーンを保存すると、シーンファイルが変わります。シーンファイルがテキスト形式で保存されていれば(Project Settings > Editor の Asset Serialization が「Force Text」の場合)、GitHub Desktopで差分を見ることで、追加したComponentの情報が記録されていることを確認できます。
WinFormsでは「画面の操作がC#のコードになる」、Unityでは「画面の操作がシーンファイルのデータになる」という違いはあります。ただ、「画面で行った操作は、どこかのファイルに記録されている」という点は同じです。
8. 補足:継承で作るか、組み合わせで作るか
WinFormsの Button は、次のように継承で機能を積み上げて作られています。
一方、UnityのButtonは、Componentの組み合わせでできていました。

この「継承で作るか、組み合わせで作るか」という違いは、設計の考え方にもつながります。詳しくは継承の次に学びたい「コンポジション」で扱っています。
(ちなみにWinFormsにも Component という名前のクラスがありますが、UnityのComponentとは別物です。名前が同じなので注意しましょう。)
まとめ
- WinFormsでは、機能がそろった完成品(
Button)をnewで作り、Controls.Add()で追加した - Unityでは、GameObjectという土台にComponentを組み合わせて「できること」を作る
- GameObjectには必ず
Transformが付き、それ以外の機能は必要なComponentを追加して持たせる - 自作スクリプトもComponentなので、
newではなくAddComponent<T>()やInspectorで付ける - 画面での操作がファイルに記録される点は、WinFormsもUnityも同じ
次は、Unityで使うC#が普通のC#とどう違うのかを見ていきましょう。
→ Unityで使うC#の特徴 ― 普通のC#と何が違うのか
その後は、次の順で進むと理解がつながります。
確認問題
- WinFormsの
ButtonとUnityのButtonの違いを、「完成品」「組み合わせ」という言葉を使って説明してください。 - 空のGameObjectを作っただけでは、画面に何も表示されません。なぜでしょうか。
- Cubeに重力で落ちる機能を持たせるには、何をすればよいですか。
new PlayerController()と書かない理由を説明してください。










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