UnityにおけるOnCollisionEnterメソッドの使用とスコア計算に関する技術資料

この技術資料では、Unityにおける物理衝突イベント処理であるOnCollisionEnterメソッドの動作、および衝突地点に基づいたスコア計算ロジックについて詳細に説明します。特に、衝突した物体が「Target」タグを持つオブジェクトである場合に、的の中心からの距離に応じたスコアを計算し、表示する方法に焦点を当てます。


1. OnCollisionEnterメソッドの基本構造

OnCollisionEnterメソッドは、Unityの物理エンジンを使用してオブジェクトが他のオブジェクトと衝突した際に呼び出されます。衝突したオブジェクトの情報はCollision型の引数に格納されます。

void OnCollisionEnter(Collision other)
{
    // 衝突時の基本処理
    GetComponent<Rigidbody>().isKinematic = true;
    GetComponent<ParticleSystem>().Play();

    // 衝突相手が「Target」タグを持つ場合の処理
    if (other.gameObject.CompareTag("Target"))
    {
        // 衝突地点と的の中心を使ったスコア計算
        // スコア表示処理
        Destroy(gameObject, 1);
    }
}

引数の説明

  • Collision other: 衝突したオブジェクトに関する情報(衝突点、コライダー、衝突相手のオブジェクトなど)を含むCollision型のオブジェクト。

2. OnCollisionEnterメソッド内の処理フロー

2.1. 物理挙動の停止とエフェクト再生

GetComponent<Rigidbody>().isKinematic = true;
GetComponent<ParticleSystem>().Play();
  • Rigidbodyの物理挙動を停止: isKinematictrueにすることで、物理エンジンの影響を受けなくなり、オブジェクトの動きが停止します。
  • エフェクト再生: 衝突時にParticleSystemを再生し、視覚的なフィードバックを提供します。

2.2. 衝突相手が「Target」かどうかの確認

if (other.gameObject.CompareTag("Target"))
{
    // 「Target」タグが付いているオブジェクトと衝突した場合の処理
}
  • タグの比較: other.gameObject.CompareTag("Target")で衝突相手のオブジェクトが「Target」タグを持っているかを確認します。これは、的に衝突したかどうかを判断するために使います。

3. 衝突位置とスコア計算の詳細

3.1. 衝突位置と的の中心位置の取得

的のオブジェクトのPivot(中心座標)は、的の接地ポイントになっています。Pivotをモデリングで的の中心に変更するか、Y座標を加算して実際の的の中心を計算することができます。これを確認するために、サンプルとしてデバッグ表示をしています。

// 衝突した相手のコライダーの中心点を取得
Vector3 colliderCenter = other.collider.bounds.center;
Debug.Log("Collider Center: " + colliderCenter);

// 的の中心位置を取得
Vector3 targetCenter3D = other.transform.position + Vector3.up * 6.5f;
Vector2 targetCenter = new Vector2(targetCenter3D.x, targetCenter3D.y);
Debug.Log("Target Center (XY): " + targetCenter);
  • collider.bounds.center: 衝突したオブジェクト(「Target」)のコライダーの中心点を3D座標として取得。
  • targetCenter: 的の中心を2D座標(Vector2)で取得し、XY平面上の座標として使用。

3.2. 衝突地点の取得

Vector3 collisionPoint3D = other.contacts[0].point;
Vector2 collisionPoint = new Vector2(collisionPoint3D.x, collisionPoint3D.y);
Debug.Log("Collision Point (XY): " + collisionPoint);
  • other.contacts[0].point: 衝突した地点を3D座標で取得し、その後xy成分のみを抽出して2D座標に変換。

3.3. 衝突地点と的の中心の距離計算

float distance = Vector2.Distance(collisionPoint, targetCenter);
  • Vector2.Distance: 衝突地点と的の中心との距離を計算。これを基に、スコアを計算します。

4. スコア計算ロジック

衝突地点と的の中心との距離に基づいてスコアを計算します。中心に近いほど高いスコアを得られ、外側に行くほどスコアが低くなります。

float maxDistance = 1.9f;
int score;

if (distance <= 0.1f)
{
    // 0.1以下の距離なら満点
    score = 10;
}
else
{
    // 距離に応じてスコアを減少
    score = (int)(Mathf.Max(0, (maxDistance - distance) / maxDistance) * 10.0f);
}
Debug.Log("Score: " + score);

4.1. スコア計算式の詳細

  • maxDistance: 的の半径、または最大スコアが得られる最大の距離です。この距離以上ではスコアが0になります。
  • distance <= 0.1: 衝突地点が中心から非常に近い場合(0.1以内)に満点の10点を与えます。
  • (maxDistance - distance) / maxDistance: 距離に応じてスコアを比例的に減少させる式です。この式により、中心に近いほどスコアが高く、外周に近いほど低くなります。

4.2. 計算式の意味

  • maxDistance - distance: 衝突地点が的の中心からどれだけ近いかを示す値です。衝突地点が中心に近いほど、この値は大きくなります。
  • / maxDistance: この値を最大距離で割ることで、0から1の範囲に正規化されます。1に近い値ほど高得点が得られます。

5. 衝突後の処理

5.1. エフェクト再生とオブジェクト削除

GetComponent<Rigidbody>().isKinematic = true;
GetComponent<ParticleSystem>().Play();
Destroy(gameObject, 1);
  • 衝突後にもう一度エフェクトを再生し、1秒後にこのオブジェクトをシーンから削除します。Destroy(gameObject, 1)により、1秒の遅延を持ってオブジェクトが削除されます。

6. まとめ

この資料では、UnityのOnCollisionEnterメソッドを使った物理的な衝突処理、および衝突位置に基づくスコア計算ロジックについて解説しました。maxDistancedistanceを使ったスコア計算の仕組みは、衝突地点が的の中心に近いほど高いスコアを得られるように設計されています。このようなスコアリングシステムは、ターゲットゲームやシミュレーションゲームなどでよく使われます。


関連リンク

C#,Unity

Posted by hidepon