【Unity】UIボタンで学ぶシンプルなポリモーフィズムの実現
UnityでUIボタンを使ってシンプルなポリモーフィズムを実現するコードの例を示します。この例では、異なる動物のクラスを作り、それぞれがボタンを押すと異なるメッセージを表示するようにします。
サンプル
まず、動物の基底クラスとその派生クラスを定義します。
クラス図
オブジェクト指向のクラスとその関係を示します。
概要: このクラス図は、オブジェクト指向プログラミングの基本的な継承関係を示しています。Animal
は抽象クラスであり、MakeSound
という抽象メソッドを持っています。Dog
とCat
はAnimal
を継承し、それぞれのクラスでMakeSound
メソッドを実装しています。これは、共通のインターフェースを持ちながら、異なる具体的な動作を実現するためのポリモーフィズムを示しています。さらに、AnimalButtonController
クラスはUIボタンを管理し、クリックイベントに応じて対応する動物オブジェクトを生成し、その動物が特定の動作を実行する役割を担っています。この構造により、コードの再利用性と保守性が向上し、新しい動物クラスを簡単に追加することが可能になります。
このクラス図は以下のような構成になっています:
Animal
は抽象クラスであり、MakeSound
という抽象メソッドを持っています。Dog
とCat
はAnimal
を継承し、それぞれMakeSound
メソッドを具体的に実装しています。AnimalButtonController
クラスは、dogButton
とcatButton
のフィールド、およびボタンがクリックされたときに動物の音を鳴らすメソッドを持っています。
このクラス図を使って、ポリモーフィズムの概念を視覚的に説明することができます。
Step 1: 動物クラスの定義
// Animal.cs
public abstract class Animal
{
public abstract void MakeSound();
}
// Dog.cs
public class Dog : Animal
{
public override void MakeSound()
{
Debug.Log("わん!");
}
}
// Cat.cs
public class Cat : Animal
{
public override void MakeSound()
{
Debug.Log("ミャー!");
}
}
Step 2: ボタンの設定とスクリプト
次に、UIボタンを設定し、ボタンを押したときに動物の音を鳴らすスクリプトを作成します。
// AnimalButtonController.cs
using UnityEngine;
using UnityEngine.UI;
public class AnimalButtonController : MonoBehaviour
{
public Button dogButton;
public Button catButton;
private void Start()
{
dogButton.onClick.AddListener(() => OnButtonClick(new Dog()));
catButton.onClick.AddListener(() => OnButtonClick(new Cat()));
}
private void OnButtonClick(Animal animal)
{
animal.MakeSound();
}
}
クラスの構造と役割
- フィールド:
dogButton
: UIのDogボタンを参照するためのフィールドです。catButton
: UIのCatボタンを参照するためのフィールドです。
- Startメソッド:
- Unityのライフサイクルメソッドの一つで、ゲームが開始されたときに呼び出されます。
- このメソッド内で、
dogButton
とcatButton
にクリックリスナーを追加します。リスナーは、ボタンがクリックされたときに特定の動作を実行するためのものです。
- OnButtonClickメソッド:
- 引数として
Animal
型のオブジェクトを受け取り、そのオブジェクトのMakeSound
メソッドを呼び出します。 Animal
は抽象クラスで、Dog
やCat
クラスはそのサブクラスとして実装されます。これにより、ポリモーフィズムを利用して異なる動物がそれぞれ異なる動作を実行できます。
- 引数として
ポリモーフィズムの利用
AnimalButtonController
クラスでは、ポリモーフィズムを利用しています。ポリモーフィズムとは、同じインターフェースや基底クラスを通じて異なるクラスのオブジェクトを同様に扱うことができる機能です。この例では、Dog
とCat
クラスがAnimal
クラスを継承しており、それぞれがMakeSound
メソッドを実装しています。
クラスの全体的な流れ
- ゲームが開始されると、
Start
メソッドが呼び出されます。 Start
メソッド内で、dogButton
とcatButton
にクリックイベントリスナーを追加します。- ユーザーが
Dog
ボタンをクリックすると、OnButtonClick
メソッドが呼び出され、新しいDog
オブジェクトが作成されます。 Dog
オブジェクトのMakeSound
メソッドが呼び出され、"Woof!"というメッセージが出力されます。- 同様に、ユーザーが
Cat
ボタンをクリックすると、新しいCat
オブジェクトが作成され、"Meow!"というメッセージが出力されます。
このように、AnimalButtonController
クラスは、ボタン操作に応じて異なる動物オブジェクトを生成し、それぞれの動物が特定の動作を実行するようにする役割を担っています。
Step 3: Unityエディターでの設定
- Unityエディターで、キャンバスを作成し、その中に2つのボタン(Dog Button、Cat Button)を配置します。
- ボタンに対応するテキスト(Dog、Cat)を設定します。
AnimalButtonController
スクリプトをアタッチするオブジェクトを作成し、スクリプトをアタッチします。AnimalButtonController
スクリプトのdogButton
フィールドにDogボタンを、catButton
フィールドにCatボタンをドラッグして割り当てます。
この設定を行うと、ボタンを押すとそれぞれの動物の音がコンソールに表示されます。これがポリモーフィズムのシンプルな実例です。同じインターフェース(ここではMakeSound
メソッド)を使って、異なるクラス(Dog、Cat)が異なる動作を実行します。
オブジェクト図
特定の時点でのシステムの状態を示します。
概要: このオブジェクト図は、Unityアプリケーション内でボタンとそれに関連するオブジェクトの状態と関係を示しています。Canvas
オブジェクトは、DogButton
とCatButton
を含んでいます。DogButton
オブジェクトは「Dog」というテキストを持ち、クリックイベントを処理します。同様に、CatButton
オブジェクトは「Cat」というテキストを持ち、クリックイベントを処理します。AnimalButtonController
オブジェクトは、dogButton
とcatButton
を操作し、それぞれのボタンがクリックされたときに対応する動物のMakeSound
メソッドを呼び出します。この図は、オブジェクト間の関係とその相互作用を視覚的に示しています。
このオブジェクト図は以下の要素を含んでいます:
- Canvasオブジェクト:
dogButton
とcatButton
を含んでいます。 - DogButtonオブジェクト: テキストが「Dog」であり、
onClick()
メソッドがあります。 - CatButtonオブジェクト: テキストが「Cat」であり、
onClick()
メソッドがあります。 - AnimalButtonControllerオブジェクト:
dogButton
とcatButton
を使用し、OnButtonClick(animal: Animal)
メソッドを持っています。
この図をもとに、実際のUnityの構成を視覚化できます。特に、AnimalButtonController
がDogButton
とCatButton
を操作する関係を示しています。
その他のUML図
シーケンス図
オブジェクト間の相互作用を時系列で示します。
概要: このシーケンス図は、ユーザーがDogButton
をクリックしたときの一連の操作を時系列で示しています。ユーザーがボタンをクリックすると、DogButton
がAnimalButtonController
のOnButtonClick
メソッドを呼び出し、新しいDog
オブジェクトを作成します。その後、Dog
オブジェクトがMakeSound
メソッドを実行し、"Woof!"という音を出します。
ユースケース図
システムの機能と外部との相互作用を示します。
概要: このユースケース図は、システムの機能とそれを利用するアクター(User)との相互作用を示しています。ユーザーはボタンをクリックすることで、「Make a sound」というユースケースが実行されます。具体的には、ユーザーがシステムのUIボタン(DogボタンまたはCatボタン)をクリックすると、システムは対応する動物のオブジェクトを作成し、その動物が音を出すという動作を行います。この図は、システムが提供する機能とユーザーの関係を視覚的に示しています。
コンポーネント図
システムの物理的な部分やコンポーネントの構造を示します。
概要: このコンポーネント図は、システムを構成する各コンポーネントとその相互関係を示しています。AnimalButtonController
は、DogButton
およびCatButton
と連携して動作します。各ボタンはUI要素として存在し、それぞれがクリックイベントを持ちます。AnimalButtonController
は、これらのボタンからのクリックイベントを受け取り、対応する動物オブジェクト(Dog
またはCat
)を生成し、その動物のMakeSound
メソッドを呼び出します。この図は、システムの各コンポーネントがどのように連携して動作するかを視覚的に示しています。
ステート図
オブジェクトの状態遷移を示します。
概要: このステート図は、ユーザーがボタンをクリックした後のアプリケーションの状態変化を示しています。ユーザーがボタンをクリックすると、システムはIdle
状態からDogButtonClicked
またはCatButtonClicked
状態に遷移します。DogButtonClicked
状態では、新しいDog
オブジェクトが作成され、"わん"という音を出します。一方、CatButtonClicked
状態では、新しいCat
オブジェクトが作成され、"ミャー"という音を出します。それぞれのアクションが完了すると、システムは再びIdle
状態に戻ります。この図は、システムがどのように異なる状態間を遷移するかを視覚的に示しています。
アクティビティ図
ワークフローやアクティビティの順序を示します。
概要: このアクティビティ図は、ユーザーがボタンをクリックした後のプロセスを示しています。ユーザーがボタンをクリックすると、プロセスはDog button clicked
またはCat button clicked
というイベントに分岐します。Dog button
がクリックされた場合、新しいDog
オブジェクトが作成され、"Woof"という音を出します。同様に、Cat button
がクリックされた場合、新しいCat
オブジェクトが作成され、"Meow"という音を出します。この図は、イベントに応じた分岐処理を視覚的に示しています。
参考(直接ボタンに表示イベントをそれぞれアタッチする方法と、コントローラークラスを使用してイベントを管理する方法の違い)
直接ボタンに表示イベントをそれぞれアタッチする方法と、コントローラークラスを使用してイベントを管理する方法の違いについて説明します。
直接ボタンにイベントをアタッチする方法
直接ボタンにイベントをアタッチする方法では、各ボタンのクリックイベントに対して直接的に処理を定義します。例えば、Unityエディターのインスペクターでボタンに対してイベントをアタッチすることができます。
using UnityEngine;
using UnityEngine.UI;
public class DirectButtonHandler : MonoBehaviour
{
public Button dogButton;
public Button catButton;
private void Start()
{
dogButton.onClick.AddListener(OnDogButtonClick);
catButton.onClick.AddListener(OnCatButtonClick);
}
private void OnDogButtonClick()
{
Dog dog = new Dog();
dog.MakeSound(); // "わん!"
}
private void OnCatButtonClick()
{
Cat cat = new Cat();
cat.MakeSound(); // "ミャー!"
}
}
コントローラークラスを使用する方法
コントローラークラスを使用してイベントを管理する方法では、イベント処理のロジックを一つのクラスにまとめ、より組織的に管理します。この方法はコードの再利用性や保守性を向上させます。
using UnityEngine;
using UnityEngine.UI;
public class AnimalButtonController : MonoBehaviour
{
public Button dogButton;
public Button catButton;
private void Start()
{
dogButton.onClick.AddListener(() => OnButtonClick(new Dog()));
catButton.onClick.AddListener(() => OnButtonClick(new Cat()));
}
private void OnButtonClick(Animal animal)
{
animal.MakeSound();
}
}
違いの比較
- コードの可読性と保守性:
- 直接アタッチ: 各ボタンに対して個別にイベント処理を記述するため、コードが散在しやすく、メンテナンスが難しくなる可能性があります。ボタンの数が増えると、コードが冗長になりがちです。
- コントローラー使用: イベント処理のロジックを一つのクラスにまとめることで、コードの見通しが良くなり、保守性が向上します。新しいボタンを追加する場合も、コントローラークラスに対して追加するだけで済みます。
- 再利用性:
- 直接アタッチ: 各ボタンに対して固有の処理が必要な場合、コードの再利用が難しくなります。
- コントローラー使用: 抽象クラスやインターフェースを使って共通の処理を定義することで、コードの再利用が容易になります。例えば、
OnButtonClick
メソッドはどの動物クラスにも対応できます。
- 拡張性:
- 直接アタッチ: 新しい種類のボタンを追加するたびに、新しいイベントリスナーを定義する必要があります。
- コントローラー使用: 新しい動物クラスを追加する場合、コントローラークラスに新しいボタンを簡単に追加できます。既存のロジックを使い回すことができるため、拡張が容易です。
- 依存関係の管理:
- 直接アタッチ: 各ボタンが個別の処理を持つため、依存関係が増えると複雑になります。
- コントローラー使用: 依存関係を一つのクラスにまとめることで、管理が容易になります。依存関係の変更があった場合でも、コントローラークラスのみを修正すれば済みます。
まとめ
コントローラークラスを使用する方法は、コードの可読性、保守性、再利用性、拡張性、依存関係の管理の面で優れています。特に大規模なプロジェクトや将来的に機能拡張が見込まれる場合には、コントローラークラスを使用する方法が推奨されます。
ディスカッション
コメント一覧
まだ、コメントがありません