コンポジションは、クラスが他のクラスのインスタンスをメンバーとして保持し、その機能を利用するデザインパターンです。以下に、コンポジションを使った簡単な例を示します。
using System;
public class Engine
{
public int HorsePower { get; private set; }
public Engine(int horsePower)
{
HorsePower = horsePower;
}
public void Start()
{
Console.WriteLine($"Engine with {HorsePower} HP started.");
}
}
public class Car
{
private Engine engine;
public Car(int horsePower)
{
engine = new Engine(horsePower);
}
public void StartCar()
{
Console.WriteLine("Car is starting...");
engine.Start();
}
}
class Program
{
static void Main()
{
Car myCar = new Car(250);
myCar.StartCar();
}
}
Engine
クラスは、エンジンを表すクラスです。HorsePower
(馬力)というプロパティと、Start
メソッドを持っています。このクラスは他のクラスに独立して使われることも可能です。Car
クラスは、車を表すクラスです。このクラスはEngine
クラスのインスタンスを内部で持っています。これはコンポジションの例です。Car
クラスのStartCar
メソッドは、まず「車が始動する」と表示し、その後Engine
のStart
メソッドを呼び出します。Car
クラスのインスタンスを作成し、StartCar
メソッドを呼び出すと、車のエンジンが始動することを示すメッセージが表示されます。Car
クラスがEngine
クラスのインスタンスを保持しており、Car
の動作にEngine
の機能を利用しています。このように、クラスが他のクラスを内部で保持して機能を利用することを「コンポジション」と呼びます。次に、Bounds
を使った簡単なプログラム例を示します。ここでは、2つのオブジェクトのBounds
が重なっているかどうかを判定します。
using UnityEngine;
public class BoundsExample : MonoBehaviour
{
public GameObject objectA; // 最初のオブジェクト
public GameObject objectB; // 2つ目のオブジェクト
void Start()
{
// 各オブジェクトのColliderからBoundsを取得
Bounds boundsA = objectA.GetComponent<Collider>().bounds;
Bounds boundsB = objectB.GetComponent<Collider>().bounds;
// Bounds同士の重なりをチェック
if (boundsA.Intersects(boundsB))
{
Debug.Log("Bounds are intersecting!");
}
else
{
Debug.Log("Bounds are not intersecting.");
}
}
}
objectA
とobjectB
のCollider
コンポーネントからBounds
を取得します。Collider.bounds
プロパティを使って、そのオブジェクトが占める空間の境界を表すBounds
が得られます。Bounds.Intersects
メソッドを使って、2つのBounds
が重なっているかどうかを判定します。重なっている場合は「Bounds are intersecting!」と表示され、そうでない場合は「Bounds are not intersecting.」と表示されます。この例では、Bounds
が2つのオブジェクトの空間的な範囲を表し、その範囲が重なっているかどうかを確認しています。これにより、オブジェクト同士の衝突を効率的に判定することができます。
コンポジションとBounds
の両方の概念が理解できるように、シンプルな例を示しました。これらの理解が進むと、さらに複雑なシステムの設計にも応用できるようになります。
GameObject同士の当たり判定などは、内部的にBoundsから座標情報を取得し、座標同士の重なり合いを見ている
Unityにおけるゲームオブジェクト同士の当たり判定は、内部的にBounds
を利用して行われています。以下のような流れで処理されます。
GameObject
は、通常、Collider
コンポーネントを持っています。これにより、そのオブジェクトの空間的な境界が定義されます。Collider
は、そのオブジェクトのBounds
を計算し、オブジェクトが占める空間を表します。たとえば、BoxCollider
、SphereCollider
、MeshCollider
などがあります。Collider
を管理し、当たり判定を行います。Bounds
を使用してオブジェクト同士の衝突を判定します。具体的には、各オブジェクトのBounds
が交差しているかどうかをチェックします。OnCollisionEnter
やOnTriggerEnter
などのコールバックメソッドを呼び出し、スクリプト側で追加の処理を行うことができます。Bounds
を使って先にオブジェクトの重なりを判断するため、パフォーマンスが向上します。特に多くのオブジェクトが存在するシーンでは、Bounds
を使った初期的なチェックで、実際の詳細な当たり判定(ポリゴン同士の衝突判定など)を行う必要があるオブジェクトを絞り込むことができます。GameObject
のCollider
を介してBounds
を利用し、空間的な重なりを検出します。このように、Bounds
はゲームオブジェクトの当たり判定において非常に重要な役割を果たしています。
この例では、車 (Car
) とエンジン (Engine
) のクラスを使ってコンポジションを説明します。Unityのコンポーネントシステムを活用して、クラスの関係性やその動作を視覚的に理解できるようにします。
Scripts
という名前のフォルダを作成し、そこでスクリプトを管理します。まず、Engine
クラスを作成し、車のエンジンとして機能するスクリプトを作ります。
using UnityEngine;
public class Engine
{
public int horsePower;
public Engine(int horsePower)
{
this.horsePower = horsePower;
}
public void Start()
{
Debug.Log($"Engine with {horsePower} HP started.");
}
}
次に、Car
クラスを作成し、Engine
クラスを内部で利用する形にします。これがコンポジションの例です。
using UnityEngine;
public class Car : MonoBehaviour
{
private Engine engine;
public int carHorsePower = 250;
void Start()
{
engine = new Engine(carHorsePower);
StartCar();
}
public void StartCar()
{
Debug.Log("Car is starting...");
engine.Start();
}
}
GameObject
を作成し、これを「Car」と名前付けします。Car
スクリプトをこの「Car」オブジェクトにアタッチします。これで、Car
クラスがEngine
クラスを内部で保持し、エンジンを起動するためにその機能を使用していることがわかります。これがコンポジションの基本的な例です。
Car
クラスがEngine
を持ち、その機能を活用するのは、ゲームオブジェクトが様々なコンポーネントを持ち、それらの機能を利用することと似ています。Bounds
使用さらに、Bounds
を使った簡単な応用例を示します。この例では、Car
が他のオブジェクトと衝突するかどうかをチェックするプログラムを作成します。
using UnityEngine;
public class BoundsExample : MonoBehaviour
{
public GameObject otherObject;
void Update()
{
Bounds carBounds = GetComponent<Collider>().bounds;
Bounds otherBounds = otherObject.GetComponent<Collider>().bounds;
if (carBounds.Intersects(otherBounds))
{
Debug.Log("Collision detected between car and another object.");
}
}
}
Car
オブジェクトにCollider
(例えば、BoxCollider
)を追加し、otherObject
フィールドに別のGameObject
を設定します。Bounds
を使ってオブジェクト間の衝突判定を行う例を示すことができます。これらの例を使って、Unityでコンポジションの概念を視覚的かつ実践的に教えることができます。学生は、実際に動く例を通じて、コンポジションの重要性とその応用方法を理解できるでしょう。