アマゾンバナーリンク

Unityで作る弾幕シューティングゲームその3 プレイヤーのショットと敵との当たり判定追加

2020年7月18日

こんにちは!ジェイです。今回は自キャラのショットと敵との当たり判定の処理を追加していきます。

プレイヤーのショットの追加

  1. Aseet>Scenes>Resources>img>Char>bl_00とbl1のPixels Per Unitを32に設定
  2. 上記の2つをHierarchyに追加
  3. CPlayerControl.csの書き換え
  4. ShotOjbのアタッチ
  5. ShotにBoxCollder2DとRigidBoxy2Dタグ(Shot)をつける
  6. EnemyにCircleCollder2DとRigidBoxy2Dとタグ(Enemy)をつける
  7. ShotにCShot.csを作成しアタッチしてプレハブ化する
  8. EnemyにCEnemy.csを作成しアタッチする
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CPlayerControl : MonoBehaviour
{
    Animator _Animator;
    // Start is called before the first frame update
    public GameObject[] ShotObjs;
    void Start()
    {
        _Animator = GetComponent<Animator>();
        Sqrt2 = 1.0f / Mathf.Sqrt(2.0f);
        InputArray["Fire1"] = 0;
        InputArray["Fire2"] = 0;
        InputArray["Fire3"] = 0;
    }
    float VX = 0;
    float VY = 0;
    float Sqrt2;
    Dictionary<string, int> InputArray = new Dictionary<string, int>();
    void CalcInput()
    {
        string[] str = { "Fire1", "Fire2", "Fire3" };
        for(int i = 0; i < str.Length; ++i)
        {
            if (Input.GetButton(str[i]))
            {
                ++InputArray[str[i]];
            }
            else
            {
                InputArray[str[i]] = 0;
            }
        }
    }
    // Update is called once per frame
    void Update()
    {
        CalcInput();
        VX = VY = 0 < InputArray["Fire3"] ? 2.5f * Time.deltaTime : 7.0f * Time.deltaTime;
 
        float x = Input.GetAxisRaw("Horizontal");
        float y = Input.GetAxisRaw("Vertical");

        if (x < 0) VX = -VX; else if(x == 0) VX = 0;
        if (y < 0) VY = -VY; else if(y == 0) VY = 0;
        // 斜め方向の速度調節
        if (VX != 0 && VY != 0)
        {
            VX = VX * Sqrt2;
            VY = VY * Sqrt2;
        }
        transform.position = CUtility.ClampPosition(new Vector3(transform.position.x+VX, transform.position.y+VY, 0));
        
        // Zキー押しっぱなしで6フレームに1度ショットを発射する
        if (0 < InputArray["Fire1"] && InputArray["Fire1"] % 6 == 0)
        {
            if (0 < InputArray["Fire3"])//低速移動中なら
            {
                LowerSpeedShot();
            }
            else // 通常移動中なら
            {
                HiSpeedShot();
            }
        }
        _Animator.SetFloat("H", x);
    }
    int[] CShot0Num = { 2, 4 };
    Vector3[] HiSpeedShotOffsetPos = 
    {
        new Vector3(-0.15f,0.8f),
        new Vector3(0.15f,0.8f),
        new Vector3(-0.45f,0.4f),
        new Vector3(0.45f,0.4f),
    };
    // 通常ショット登録
    void HiSpeedShot()
    {
        //	Power < 200 ?0 : 1
        for (int i = 0; i < CShot0Num[1]; i++)
        {
            //SGP.Shot.Add(new CShot(X + CShot0Pos_X[i], Y + CShot0Pos_Y[i], 0.75f, 10));
            Instantiate(ShotObjs[0], transform.position+ HiSpeedShotOffsetPos[i], Quaternion.identity);
        }
    }
    Vector3[] LowerSpeedShotOffsetPos =
{
        new Vector3(-0.05f,0.8f),
        new Vector3(0.05f,0.8f),
        new Vector3(-0.25f,0.4f),
        new Vector3(0.25f,0.4f),
    };
    //低速通常ショット登録
    void LowerSpeedShot()
    {
        for (int i = 0; i < CShot0Num[1]; i++)
        {
            //SGP.Shot.Add(new CShot(X + CShot0Pos_X[i], Y + CShot0Pos_Y[i], 0.75f, 10));
            Instantiate(ShotObjs[0], transform.position + LowerSpeedShotOffsetPos[i], Quaternion.identity);
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class CShot : MonoBehaviour
{
    public float Speed = 3.0f;
    public int ShotPower = 1;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        float angle = 90.0f;
        transform.position += CUtility.GetDirection(angle) * Speed * Time.deltaTime;

        // 弾が進行方向を向くようにする
        var angles = transform.localEulerAngles;
        angles.z = angle - 90;
        transform.localEulerAngles = angles;

        // 2 秒後に削除する
        Destroy(gameObject, 2);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class CEnemy : MonoBehaviour
{
    int Cnt = 0;
    int Life = 60;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Cnt < 100)
        {
            transform.position += new Vector3(0.0f, -3.0f, 0.0f) * Time.deltaTime;
        }
        if (Cnt > 100 + 240)
        {
            transform.position += new Vector3(0.0f, 3.0f, 0.0f) * Time.deltaTime;
        }
        Cnt++;
        if(CUtility.IsOut(transform.position))
        {
            Destroy(gameObject);
        }
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.tag == "Shot")
        {
            Life -= collision.GetComponent<CShot>().ShotPower;
            if (Life <= 0)
            {
                Destroy(gameObject);
            }
            Destroy(collision.gameObject);
        }
    }
}

以上でショットと敵の当たり判定が実装できます。

この時に注意する点が、OnTriggerEnter2Dを使用する際には、ColliderのIsTriggerにチェックを入れるというのと、当たり判定をするオブジェクトのどちらかにRigidBody2Dをつけるということです。

今回のプロジェクトはこちらからダウンロードできます。