Unityで物理演算でオブジェクトを動かし壁にぶつかったらぴったり止める方法/Rigidbody.Velocityの使い方

the-stopper IT

リジッドボディのコンポーネントを操作することでオブジェクトを移動し、壁に接触したら止まるようにしてみます。

スポンサーリンク

成果物

transform.Translateによる例

goal1
まずはオブジェクトをふたつ置いておきます。
goal2
キツネはリジッドボディコライダーを設置、リジッドボディは重力スケールを0にして、自由落下しないようにしておきます。
ブロックもコライダーを付けておきます。
goal3
transform.Translateを使ってキー操作でオブジェクトを移動するスクリプトを書いて、
goal4
オブジェクトにアタッチします。
mv1
これでキー操作でキツネが動く状態になっていますが、この状態で壁にぶつかると、
mv2
キツネが無理矢理壁にめりこんでいきます(キーを離すと外に押し出される)。

なんでかというと、transform.Translateは強制的に位置を変更する命令なので、物理演算的にはおかしな動きもしてしまうからです。
というわけで、ちゃんと物理演算する命令を使います。

Rigidbody.Velocityの使い方

同じくキー操作で動くスクリプトで、制御をRigidbody経由で行います。
構文は下記の通りです。

物理演算でオブジェクトを移動させる(2D)
オブジェクト.GetComponent<Rigidbody2D>().velocity = new Vector2(x,y);
goal6
velocity速度です。さっきのコードの処理部分を書き換えて実行すれば、
mv3
こんな感じで、壁(コライダー)にぶつかるとしっかり止まるスクリプトになります……が。
mv4
velocityは変更して何もしないとずっとその値がキープされるので、キーから指を離しても動き続けます。
滑る床にでもしたくないのであれば、コードの最初にvelocityを0にする命令を書いておく必要があります。

※より厳密には、関数はUpdateではなくFixedUpdateを使うべきです(Updateは機種によって処理速度が変化し、一定の動作が得られないため)。

//Unity C#
    void Update()
    {
    //初期化
    this.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 0);
        //左
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            this.GetComponent<Rigidbody2D>().velocity = new Vector2(-100, 0);
        }
        //右
        if (Input.GetKey(KeyCode.RightArrow))
        {
            this.GetComponent<Rigidbody2D>().velocity = new Vector2(100, 0);
        }
        //上
        if (Input.GetKey(KeyCode.UpArrow))
        {
            this.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 100);
        }
        //下/span>
        if (Input.GetKey(KeyCode.DownArrow))
        {
            this.GetComponent<Rigidbody2D>().velocity = new Vector2(0, -100);
        }
    }

コメント