Menu
CoddyTech

パドルで狙う

Coddyの「Unityゲーム:ブロック崩し」コースのレッスン 4/16。

完全な跳ね返りでは、プレイヤーは狙いを定められません。ボールは入ってきた角度のままパドルから離れます。ブロック崩しゲームでは、代わりにパドルで方向を決めます。左端近くに当たるとボールは左上に飛び、中央に当たると真上に飛び、中央から離れるほど角度が大きくなります。

当たった位置を、左端で -1、右端で 1 となる数値に変換します。つまり、ボールの x 座標とパドルの中心とのずれを、パドルの幅の半分で割ります。たとえば、パドルの幅が 4 単位で中心が x = 2 にあり、ボールが x = 3 で当たったとします。ずれは 1、幅の半分は 2 なので、数値は 0.5 です。新しい方向は、横に 0.5、上に 1 の (0.5, 1, 0) を正規化したものになります。端のちょうど上に当たると 1 または -1 になり、真上から 45 度の角度になります。ボールがパドルの角に触れると、端を少し越えることがあるため、この数値をその範囲内に収めてください。

ボールの OnCollisionEnter は物理演算が跳ね返りを計算した後に実行されるため、そこで速度を設定すると、それが元の速度に置き換わります。壁も同じメッセージを送るので、壁では通常の跳ね返りを維持する必要があります。そのため、まず何に当たったかを確認してください。collision.collider.bounds は、スケールを含む、コライダーがワールド内で占めるボックスです。

void OnCollisionEnter(Collision collision)
{
    Bounds box = collision.collider.bounds;
    Debug.Log(collision.gameObject.name + " is " + box.size.x + " wide, centered at x = " + box.center.x);
}
challenge icon

チャレンジ

簡単

BallにOnCollisionEnter(Collision collision)を追加します。

  1. 衝突したオブジェクトにPaddleタグが付いていない限り、何もしません。
  2. xを計算します。ボールのx座標からパドルのx座標を引き、その値をパドルの幅の半分(collision.collider.bounds.size.x)で割り、-1から1の範囲に収めます。
  3. Rigidbodyの速度をnew Vector3(x, 1f, 0f)の正規化した値にspeedを掛けたものに設定します。

Playを押し、パドルの両端付近でボールを受け止めてから、Checkを押します。

自分で試してみよう

using UnityEngine;
using UnityEngine.InputSystem;

public class Ball : MonoBehaviour
{
    public Transform paddle;
    public float speed = 9f;

    Rigidbody rb;
    bool launched;

    void Awake()
    {
        rb = GetComponent<Rigidbody>();
        PhysicsMaterial bouncy = new PhysicsMaterial("Bouncy");
        bouncy.bounciness = 1f;
        bouncy.dynamicFriction = 0f;
        bouncy.staticFriction = 0f;
        bouncy.bounceCombine = PhysicsMaterialCombine.Maximum;
        bouncy.frictionCombine = PhysicsMaterialCombine.Minimum;
        GetComponent<Collider>().material = bouncy;
    }

    void Update()
    {
        if (launched) return;
        transform.position = paddle.position + Vector3.up * 0.5f;
        if (Keyboard.current.spaceKey.wasPressedThisFrame) Launch(new Vector3(0.3f, 1f, 0f));
    }

    public void Launch(Vector3 direction)
    {
        launched = true;
        rb.linearVelocity = direction.normalized * speed;
    }

    void FixedUpdate()
    {
        if (!launched) return;
        rb.linearVelocity = rb.linearVelocity.normalized * speed;
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Unityゲーム:ブロック崩しのすべてのレッスン