コンポジションは、クラスが他のクラスのインスタンスをメンバーとして保持し、その機能を利用するデザインパターンです。以下に、コンポジションを使った簡単な例を示します。
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でコンポジションの概念を視覚的かつ実践的に教えることができます。学生は、実際に動く例を通じて、コンポジションの重要性とその応用方法を理解できるでしょう。