【Unity2d】衝突判定をトリガーにオブジェクトを加速させる

Unity2D

Unity2D ARPG

こんにちは。なおキーヌです。

ブログ毎日更新は347日目になります。

前回ゴブリンにハンマーを当てたらOnCollisionEnter関数を動かすことができました。

トリガーを利用して衝突したらゴブリンを吹っ飛ばす(ノックバック)仕組みを作りましょう。

ノックバックの仕組みを作るには

ノックバックは素人が見ても物理を使った移動というのがわかると思います。

力を加えるとその方向に加速し、摩擦による減速で停止といった感じです。

こういったことをパっと実装したい時に数学や物理の知識が乏しいと苦労しますね。

ゲームを作りたい学生さんは数学と物理を徹底的に勉強すべきです!

が、恐らくUnityであればRigidBodyを使ったりAddForceを使えば簡単に実装できます。

試しに実装してみましょう。

Unityの機能を使ったノックバック

RigidBodyを使ってCollision同士をぶつからせると物理演算が発動しますよね。

これを利用してノックバックさせてみましょう。

理想はハンマーが当たったらその力で動かしたいのですが、
ハンマーはアニメーションにより強制で移動しているのでハンマー自体に加速度はありません。

ゴブリンのノックバックはRigidBodyを利用してハンマーが衝突したときに
ゴブリンそのものに加速度を与えるという方法で実装します。

RigidBodyにはAddForceという加速させる仕組みがあるのでそれを利用します。

2DなのでVector2を数値で与えてやるとその方向に加速します。

初動の力を与えて動かし、ゴブリンそのものが持つ重量で自動的に摩擦での減速を行い
良い感じにノックバックを実装してみましょう。

ゴブリンにアタッチしているスクリプトのStartにAddForceを適用してみます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SmallEnemyCollision : MonoBehaviour
{
    private Rigidbody2D rb;
    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        rb.AddForce(transform.up * 1000.0f);
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void OnCollisionEnter2D(Collider2D other) {
        Debug.Log("ダメージ!");

    }
}

これで実行してみるとゴブリンが上にスイーッって動くと思います。

上手く動かないときはRigidBody2Dにある重力や摩擦の数値を色々いじくっていい感じにスライドするようにしてみます。

トリガーで加速させる

衝突判定トリガーとオブジェクトの加速を覚えたので組み合わせて
武器が当たった時に当てられた側のオブジェクトを加速させてみましょう。

ハンマーのBoxCollider2DのisTriggerにチェックを入れるのを忘れないようにしましょう。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SmallEnemyCollision : MonoBehaviour
{
    private Rigidbody2D rb;
    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void OnCollisionEnter2D(Collider2D other) {
        rb.AddForce(transform.up * -1000.0f);
        Debug.Log("ダメージ!");

    }
}

単純にOnCollisionEnter2Dに処理を持ってきて、座標を一旦下方向に進むようにしました。

が、ここで問題が発生!

判定にあたるとちゃんと動くのですが、アニメーションさせた衝突判定は
なぜか認識しれくれませんでした。

よく見たらOnCollisionEnter2DじゃなくてOnTriggerEnter2Dを使わないとダメみたいですね。

ちゃんと読んでない証拠です(笑)

それでは書き替えてみましょう。


    private void OnTriggerEnter2D(Collider2D other) {
        rb.AddForce(transform.up * -1000.0f);
        Debug.Log("ダメージ!");

    }

これで良い感じに動いてくれました!

OnTriggerEnter2Dにより衝突判定同士がぶつかったら駆動するスクリプトを、
ゴブリンが身に付けているので関数が発動するとAddForceによる加速が行われます。

現状、どこにぶつかっても1方向にしか動かないので不自然さを解消させたいです。

当たった位置によって加速度を決める

ハンマーは現状アニメーションによって強制的に位置を変更して動かしています。

3Dと違って2Dはコマ毎に動いているので、アニメーションのコマのどのときに当たったのかで
加速させるベクトルを決めることが出来ます。

例えば下向きで攻撃ボタンを押した直後はハンマーが出始めの状態で、
左側にハンマーヘッドがある状態です。

その状態に当たるとハンマーを出した直後の力(画面左に吹っ飛ぶ力)が加わることがわかります。

本来であればモンスターのどこに当たったのかも加味したいですが、
それをUnityでスクリプトを使って書くのはあまりにもツールの無駄遣いとなってしまいます。

なので初動のハンマーは強制的にモンスターを左に押し出す力を与えるといいでしょう。

その際にモンスターがハンマーの上下どちらに居るかを判定して軽く上下に吹っ飛ばす力を加えれば
幾分自然に見えるかもしれません。

次回は当たった位置によって吹っ飛ばす位置を変えてみましょう。

それでは。