見出し画像

ユニティちゃんを操作してみる (2) - 物理演算

ユニティちゃんを物理演算で制御する手順をまとめました。

・2021.3.6f1

前回

1. Rigidbodyの追加

「Rigidbody」は、重力を加えたり、任意の方向に力を加えたりするなど、ゲームオブジェクトを物理演算で制御できるようにするためのコンポーネントです。

(1) ユニティちゃんに「Add Component」で「Rigidbody」を追加。
(2) 「Rigidbody」を以下のように設定。

・Mass : 1
・Drag : 0
・Angular Drag : 0.05
・Use Gravity : true
・Is Kinematic : false
・Interpolate : None
・Collision Detection : Discrete
・Constraints
 ・Freeze Position = (false, false, false)
 ・Freeze Rotation = (true, false, true)

各設定項目の意味は、次のとおりです。

Mass : 物体の質量 (kg)
・Drag:力によって動く際の空気抵抗の大きさ (0:抵抗なし, 無限:即静止)
・Angular Drag:トルクによって回転する際の空気抵抗の大きさ (0:抵抗なし, 無限:即静止)
・Use Gravity:重力を有効にするかどうか
・Is Kinematic:物理演算を無効(Transformのみによって操作)にするかどうか
・Interpolate:動きをスムーズにするための補完方法
・Collision Detection:高速移動時の衝突のすり抜けを防ぐ方法
・Constraints:動きの制限

(3) Playボタンで実行して動作確認
実行すると、ユニティちゃんが床をすり抜けて落ちていきます。

2. Colliderの追加

「Collider」は、衝突判定のための形状を設定するコンポーネントです。形別に6種類あります。

Box Collider : 3D用の立方体型のCollider
Sphere Collider : 3D用の球型のCollider
Capsule Collider : 3D用のカプセル型のCollider
2D Box Collider : 2D用の正方形型のCollider
2D Circle Collider : 2D用の円型のCollider
Mesh Collider : メッシュ状のCollider

(1) ユニティちゃんに「Add Component」で「Capsule Collider」を追加。
(2) 「Rigidbody」を以下のように設定。
Sceneビューで確認しながら大きさをあわせます。

・Center : (0, 0.5, 0)
・Radius : 0.3

各設定項目の意味は、次のとおりです。

・Is Trigger : true時は物理挙動を無効にし、衝突判定のみ行う
・Material : Colliderで使用するマテリアル
・Center : カプセルの中点
・Radius : カプセルの半径
・Height : カプセルの高さ
・Direction : 向き (X-Axis, Y-Axis, Z-Axis)

(3) Playボタンで実行して動作確認
実行すると、こんどは床をすり抜けません。

床の端まで行くと落ちます。

3. Rigidbodyに力を加える

「Rigidbody」に力を加えて、ユニティちゃんをジャンプさせます。

(1) コードを以下のように編集。

・UnityChanTest.cs

using UnityEngine;
using System.Collections;

// ユニティちゃんの動作テスト
public class UnityChanTest : MonoBehaviour {
    Animator animator;
    Rigidbody rb;

    // スタート時に呼ばれる
    void Start () {
        animator = GetComponent<Animator>();
        rb = GetComponent<Rigidbody>();
    }

    // 定期時間毎に呼ばれる
    void FixedUpdate () {
        // 前進
        if (Input.GetKey("up")) {
            transform.position += transform.forward * 0.05f;
            animator.SetBool("is_running", true);
        } else {
            animator.SetBool("is_running", false);
        }

        // 左右回転
        if (Input.GetKey("left")) {
            transform.Rotate(0, -5, 0);
        } else if (Input.GetKey("right")) {
            transform.Rotate(0, 5, 0);
        }
    }

    // フレーム毎に呼ばれる
    void Update () {
        // ジャンプ
        if (Input.GetKeyDown("space")) {
            // 着地時
            if (Mathf.Abs(rb.velocity.y) <= 0.0001f) {
                rb.AddForce(transform.up * 200f, ForceMode.Force);
            }
        }
    }
}

「Rigidbody」のAddForce()で力ベクトル、AddTorque()でトルク(回転力)ベクトルを加えます。

rb.AddForce(Vector3 v, ForceMode mode)
rb.AddTorque(Vector3 v, ForceMode mode)

「ForceMode」には、以下の定数を指定します。「質量」を考慮すると、重いほど動きにくくなります。「継続的」に力を加える場合は毎フレーム(FixedUpdate)、「瞬間的」に力を加える場合は1フレームで呼び出します。

・ForceMode.Force : 質量を考慮して継続的に力を加える
・ForceMode.Acceleration :  質量を無視して継続的に力を加える
・ForceMode.Impulse : 質量を考慮して瞬間的に力を加える
・ForceMode.VelocityChange : 質量を無視して瞬間的に力を加える

Rigidbodyから速度と角速度を取得することもできます。

・velocity : 速度 (m/s)
・angularVelocity : 角速度(rad/s)

(2) Playボタンで実行して動作確認
スペースキーでジャンプできることを確認します。

立方体を配置して、登れることも確認します。

4. Collisionイベントの追加

次に、ユニティちゃんが左の立方体と衝突したら、赤色に変わるようにします。

(1) 左の立方体にタグ「CubeL」を追加。
「Add Tag」で「CubeL」という名前のタグを追加してから選択します。

(2) ユニティちゃんのコードに以下のメソッドを追加。

・UnityChanTest.cs (一部)

// 他のオブジェクトとの衝突開始
void OnCollisionEnter(Collision collision) {
    if (collision.gameObject.tag == "CubeL") {
        collision.gameObject.GetComponent<Renderer>().material.color = Color.red;
    }
}

「Collider」を持つオブジェクト同士が衝突すると、以下のメソッドが呼ばれます。

OnCollisionEnter(Collision collision) : 他のオブジェクトと衝突開始
OnCollisionExit(Collision collision) : 他のオブジェクトと衝突終了
OnCollisionStay(Collision collision) : 他のオブジェクトと衝突中

(3) Playボタンで実行して動作確認
実行して、左の立方体に触ると赤色になります。

5. Triggerイベントの追加

ユニティちゃんが右の立方体をすり抜けたら、緑色が変わるようにします。

(1) 右の立方体にタグ「CubeR」を追加。
「Add Tag」で「CubeR」という名前のタグを追加してから選択します。

(1) 立方体の「Collider」の「Is Trigger」にチェックを入れる。
「Trigger」が有効だとすり抜け(物理演算しない)、無効だとすり抜けない(物理演算する)設定になります。

(2) ユニティちゃんのコードに以下のメソッドを追加。

// 他のオブジェクトとのすり抜け開始
void OnTriggerEnter (Collider other) {
    if (other.gameObject.tag == "CubeR") {
        other.gameObject.GetComponent<Renderer>().material.color = Color.green;
    }
}

「Collider」を持つオブジェクト同士が衝突すると、片方の「Collider」の「Is Trigger」が有効な時、以下のメソッドが呼ばれます。

OnTriggerEnter(Collider collider) : 他のオブジェクトとすり抜け開始
OnTriggerExit(Collider collider) : 他のオブジェクトとすり抜け終了
OnTriggerStay(Collider collider) : 他のオブジェクトとすり抜け中

(3) Playボタンで実行して動作確認
実行して、右の立方体に触ると緑色なります。

【おまけ】 APIリファレンス


この作品はユニティちゃんライセンス条項の元に提供されています


この記事が気に入ったらサポートをしてみませんか?