ノックバック
CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 57/71。
ノックバックとは、何かにぶつけられたとき、そのぶつけたものから離れる方向に押し飛ばされることです。ぶつけたものからぶつけられたものへと伸びる線に沿った、1回の衝撃です。このバンパーは、ぶつかってきたものすべてをノックバックさせます。
[SerializeField] private float power = 8f;
void OnCollisionEnter(Collision collision)
{
Vector3 away = collision.transform.position - transform.position;
away.y = 0f;
collision.rigidbody.AddForce(away.normalized * power, ForceMode.Impulse);
}collision.transform.position - transform.positionは、バンパーからぶつかってきたものへ向かうベクトルです。押し飛ばす力が水平になるよう、yを0に設定します。また、normalizedを使うと、2つの中心がどれだけ離れていてもベクトルの大きさは同じになります。ForceMode.Impulseは1回限りの衝撃です。速度を質量で割ったpowerの分だけ一度に変化させるため、質量2のボールは質量1のボールの半分の速さで飛んでいきます。デフォルトのForceMode.Forceは各ステップで加えることを想定しており、1ステップ分の力はその50分の1です。
速度が上書きされない間だけ、衝撃の効果は続きます。FixedUpdateで各ステップに矢印キーからrb.linearVelocityを設定するプレイヤーは、1ステップ後にその効果を失います。そのため、そのようなスクリプトでは、衝突後しばらく速度を変更しないようにするか、力を使ってプレイヤーを動かす必要があります。
チャレンジ
中級プレイヤーがSpaceキーで衝撃波を発生させられるようにします。
Input.GetKeyDown(KeyCode.Space)で、プレイヤー自身のコライダーをスキップしながらforeach (Collider hit in Physics.OverlapSphere(transform.position, radius))をループします。hit.TryGetComponent(out Rigidbody body)ごとに、away = hit.transform.position - transform.positionを設定し、away.y = 0fにします。body.AddForce(away.normalized * power + Vector3.up * lift, ForceMode.Impulse);を呼び出します。
「プレイ」を押し、木箱の間でSpaceキーを押します。その後、「確認」を押します。
自分で試してみよう
using UnityEngine;
public class Shockwave : MonoBehaviour
{
[SerializeField] private float radius = 4f;
[SerializeField] private float power = 6f;
[SerializeField] private float lift = 2f;
void Update()
{
// Spaceキーを押したら、radius内のすべてのRigidbodyをプレイヤーから遠ざかる方向に押し出す
}
}
物理演算とゲームプレイのすべてのレッスン
自分で練習してみよう: Unityプレイグラウンド