速度を保つ
Coddyの「Unityゲーム:ブロック崩し」コースのレッスン 3/16。
Brick Breaker のボールは決して減速しません。大部分は PhysicsMaterial が担います。反発係数を 1 にすると、跳ね返る際の速度がすべて保たれ、摩擦を 0 にすると、壁がボールを引きずったり回転させたりするのを防ぎます。壁やブロックには独自のマテリアルがなく、Unity は2つのコライダーの値を組み合わせます。デフォルトの Average では、ボールの 1 と壁のデフォルト値 0 によって、跳ね返ったときの速度は半分になります。bounceCombine = Maximum と frictionCombine = Minimum を設定すると、ボール自身の値が、ぶつかる相手の値より優先されます。
それでも物理演算は厳密ではありません。動いているパドルは跳ね返りに自身の速度を加え、2つのボールは互いに押し合い、小さな誤差が何百回もの跳ね返りで積み重なります。そこで、ボールは毎回の FixedUpdate で方向を保ち、速度を設定し直します。また、Ball の Rigidbody では、Inspector で Freeze Position Z にチェックが入っており、プレイ平面上にとどまるようになっています。
別のゲームでは、異なるルールが必要です。エアホッケーのパックは減速してもよいものの、速度が上限を超えてはいけません。Vector3.ClampMagnitude は、長すぎるベクトルを短くし、それより短いベクトルはそのままにします。
void FixedUpdate()
{
rb.linearVelocity = Vector3.ClampMagnitude(rb.linearVelocity, maxSpeed);
}ボールには上限を設けるだけでは不十分です。速度が毎秒 2 単位まで落ちると、そのまま 2 のままになります。ボールには、方向に基づいて速度を正確に設定する必要があります。
チャレンジ
簡単Ballでは:
Awake()で、bounciness が 1、dynamic friction と static friction が 0、bounceCombineが Maximum、frictionCombineが Minimum のnew PhysicsMaterial("Bouncy")を作成し、GetComponent<Collider>().materialを使ってボールのコライダーに割り当てます。FixedUpdate()を追加します。ボールが発射されている間、その現在の方向にspeedを掛けた値をlinearVelocityに設定します。
Unity では、マテリアルをアセットとして作成(Create > Physics Material)して Sphere Collider の Material スロットにドラッグすることもできます。ここではスクリプトで作成します。
再生を押してボールを発射し、跳ね返る様子を確認してから、チェックを押します。
自分で試してみよう
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>();
}
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;
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。