キネマティックボディ
CoddyのUnityジャーニー「物理演算とゲームプレイ」セクションの一部。レッスン 6/71。
動く足場、リフト、ドアは固体オブジェクトのように衝突する必要がありますが、その上に乗ったものによって落下したり押し動かされたりしてはいけません。これはキネマティックボディです。rb.isKinematic = trueを設定すると、重力、力、衝突によって動かされなくなります。コライダーは引き続き有効なので、動的ボディ(物理演算によって動くボディ)は壁にぶつかるように衝突し、床に立つようにその上に乗ります。キネマティックボディは、rb.MovePositionを使って自分で動かします。
このリフトはlift m/sで上昇し、topに達すると止まります。MovePositionには、このステップの後にある位置を渡すため、コードではTime.fixedDeltaTimeを使って、1ステップ分の移動量を加えています。
void Start()
{
rb = GetComponent<Rigidbody>();
rb.isKinematic = true;
}
void FixedUpdate()
{
if (rb.position.y < top)
{
rb.MovePosition(rb.position + Vector3.up * lift * Time.fixedDeltaTime);
}
}transform.positionを設定しないのはなぜでしょうか?それではオブジェクトが瞬間移動し、物理演算はその移動を認識できません。そのため、滑る足場に乗った木箱は一緒に運ばれず、取り残されてしまいます。MovePositionは、ステップ中にボディが新しい位置まで移動したことを物理演算に伝えるので、接触しているものは適切に運ばれ、押されます。キネマティックボディに対してAddForceを呼び出しても何も起きません。また、キネマティックボディは静的コライダーとも、ほかのキネマティックボディとも衝突しません。衝突するのは動的ボディだけです。
チャレンジ
簡単はしけを溶岩の上に浮かせ、矢印キーで滑らせましょう。
Start()で、rb.isKinematic = true;を設定します。FixedUpdate()で、float h = Input.GetAxisRaw("Horizontal");を読み取り、rb.MovePosition(rb.position + Vector3.right * h * speed * Time.fixedDeltaTime);を呼び出します。
「プレイ」を押して滑らせましょう。はしけは空中に浮かび、ドローンは跳ね返ります。その後、「確認」を押します。
自分で試してみよう
using UnityEngine;
public class Barge : MonoBehaviour
{
public float speed = 2f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
// はしけをキネマティックにする
}
void FixedUpdate()
{
// 矢印キーではしけをx軸に沿ってスライドさせる
}
}
物理演算とゲームプレイのすべてのレッスン
自分で練習してみよう: Unityプレイグラウンド