Unityの2Dアセット騎士に攻撃判定をつけてみた


2D騎士を用いたゲーム

剣士が1対1で戦うゲームを作ってみたかったので、
Unityを使って騎士ドット絵を使って作ろうと思った。
Unityは初めてだったので、考えることが少なそうな2Dゲームで作ろうとした。
↓のAssetを使ってみた。
https://assetstore.unity.com/packages/2d/characters/hero-knight-pixel-art-165188
しかし問題が...
2Dドット絵は武器にcolliderつけても、攻撃時にcolliderがくっついて動いてくれない。
(3Dは人型モデルの武器・手足にcolliderつければ当たり判定が効く。)
そこで、どうにか攻撃判定させる方法を考えてみた。

Colliderによる攻撃判定

Colliderに関する詳細な説明は「引用・参考文献」をご覧ください。

1.Collider同士がぶつかると

例えばボールが重力で落ちて、箱にぶつかるとする。
ボールと箱それぞれにcolliderをつけると、落ちたボールが箱に当たるようになる。
このcolliderを用いて、当たり判定をつけることができる。
ボールと箱のそれぞれにcollider2Dをつけ、ボールにrigidbody2D(物理エンジン)をつける。
ボールが重力で落ちて箱に当たると、箱が赤くなる。

2.Triggerによる当たり判定

例えば、横にボールを動かして当てるとする。
動くボールが重力で落ちないように、rigidbody2Dを「Kinematic」にする。
そうすると当たらずにすり抜けてしまう。

Kinematicの場合は、collider同士が当たってもすり抜けてしまう。
この場合は、colliderのどちらか(今回は四角)に「Is Trigger」をつける。

Is Triggerはすり抜ける際に当たり判定が起こるモードである。

Triggerで当ててみると、当たったとき(正確にはボールが四角の中に入ったら)
箱が緑色になった。

2Dゲームなどでは横に攻撃することが多いため、
横移動オブジェクトをtriggerで判定させれば攻撃判定が作れる。

攻撃判定のつけ方 “攻撃オブジェクト”

攻撃オブジェクトと攻撃判定のスクリプト, 受け側の判定スクリプトを紹介する。

1.攻撃オブジェクト


騎士の首元に丸いオブジェクトを配置
これを「攻撃オブジェクト」とする。
攻撃オブジェクトにはCircul colliderをつけておく。(サイズはオブジェクトと同程度)
丸いオブジェクトは2D ObjectのSpriteを新しく作って適当に丸くした。
攻撃オブジェクトにRigidbody2Dをつけておく。
(よく忘れがち。Collider判定する場合はぶつかるもののどちらかにつける。)

攻撃オブジェクトに下記設定のPhysics 2Dをつけた。
重力で落ちないように、「Kinematic」にした。

↓攻撃オブジェクトを動かすスクリプトは下記の通り。

AttackController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AttackControllerTest : MonoBehaviour
{
    Rigidbody2D rd; //Rigidbodyオブジェクト
    float attspeed = 6.0f;  //オブジェクト移動スピード

    void Start()
    {
        rd = GetComponent<Rigidbody2D>();   //Rigidbodyコンポーネント取得
    }

    void Update()    
    {
        if(Input.GetKeyDown(KeyCode.Space))     //攻撃開始時(Spaceキーを押すと攻撃開始)
        rd.velocity = new Vector2(attspeed, 0); //スピードをつけて攻撃オブジェクトを移動
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        Destroy(gameObject);    //攻撃オブジェクトの破棄
    }
}

Spaceキーを押すと騎士攻撃が始まり、それと同時に攻撃オブジェクトが前方へ行く。
攻撃オブジェクトは速度6.0fで右へ向かっていく。
OnTriggerEnter2dになったら(Colliderがもう一方のcolliderに入り込んだら)
オブジェクトが破棄されるようにした。(敵に当たったら消える)

2.受けキャラの受け判定

敵役の鬼?の首元にBox colliderをつける。

鬼用colliderのサイズ・XYは下図のように調整しました。
鬼のcolliderを「Is Trigger」にした。

↓鬼が攻撃オブジェクトを受けるときに、倒れるためのスクリプト

BanditController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BanditController : MonoBehaviour
{
    Animator animator;    //アニメオブジェクト

    // Start is called before the first frame update
    void Start()
    {
        this.animator = GetComponent<Animator>();  //アニメコンポーネントの取得
    }


private void OnTriggerEnter2D(Collider2D collision)
    {
        animator.SetTrigger("Death");   //倒れるアニメに移行
    }
}

OnTriggerEnter2dになったら(攻撃オブジェクトが鬼に入り込んだら)
鬼が倒れるようにしてる。

試しに切ってみた

騎士が鬼を切ってみる。

攻撃オブジェクトが鬼の首についたら、鬼が倒れた。


攻撃オブジェクトを透明にしてもう一度。
剣で切るのと、攻撃オブジェクトが当たるのがちょうどいい。


攻撃オブジェクトの速度を倍にしてみた。
速度が速すぎるとと剣切る前に倒れる。(斬撃をかわす?)


逆に遅いと、切られてることに気づいていない。
剣士「振り向くなっ!」

最後に

https://www.youtube.com/watch?v=a8bI_725U7k
2Dで↑のようなゲームが作れた。
1対1のバトルなら攻撃オブジェクトも有用かもしれないが、
騎士を動かして沢山の敵を倒すアクションRPGは難しいかも...

引用・参考文献

この記事には基本的なことはほぼ書いていませんでした。すみません...
そのくらいUnityは奥が深いですね笑

https://qiita.com/azumak/items/b45e90705e25bd9d49d0
https://qiita.com/kanatatara/items/363a3a429dfa9cb2b92c
https://www.sejuku.net/blog/58775
当たり判定やcolliderについて解説している記事・サイト。

https://www.sejuku.net/blog/51770
今回省略した物理エンジンの要・rigidbodyについて解説しています。

https://www.sbcr.jp/product/4815606657/
(書籍)Unityの教科書
私はこれでUnityや当たり判定を学びました。
今回使用したrigidbodyや基本的なUnityの使い方が全て書いてあります。