Week05_Skills - M-634/unity-game-dev-tutorial GitHub Wiki

Week05 - 自動攻撃システムの実装


🎯 ゴール

  • プレイヤーが一定間隔で自動的に攻撃(弾)を撃てるようにする
  • 攻撃間隔(クールタイム)の制御方法を理解する
  • 複数の攻撃スキルを同時に持ち、違う方向・速度・発射間隔で発動できるようにする
  • 自動攻撃システムの拡張に備えた柔軟な設計を学ぶ
  • ScriptableObjectに触れてみる

📚 授業ステップ

✅ ステップ①:単一スキルの自動攻撃

スキルデータクラス作成

📄 AutoAttackSkill.cs

[System.Serializable]
public class AutoAttackSkill 
{
    public string name;
    public GameObject bulletPrefab;
    public float interval;
    public float speed;
    public Vector2 direction;
}

📄 PlayerAutoAttack.cs(単発バージョン)

using UnityEngine;

public class PlayerAutoAttack : MonoBehaviour
{
  [SerializeField]
    private AutoAttackSkill _skill;

    [SerializeField]
    private Transform _muzzle;

    private float _timer;

    private void Update()
    {
        _timer += Time.deltaTime;

        if (_timer >= _skill.interval)
        {
            Shoot();
            _timer = 0f;
        }
    }

    private void Shoot()
    {
        GameObject bullet = Instantiate(_skill.bulletPrefab, _muzzle.position, Quaternion.identity);
        Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
        rb.velocity = _skill.direction.normalized * _skill.speed;
    }
   
}

ここで一旦動作確認

✅ ステップ②:複数スキル対応

#### 📄 PlayerAutoAttack.cs(複数スキル対応)

using UnityEngine;
using System.Collections.Generic;

public class PlayerAutoAttack : MonoBehaviour
{
    [SerializeField]
    private List<AutoAttackSkill> _skills = new();

    [SerializeField]
    private Transform _muzzle;

    private List<float> _timers = new();

    private void Start()
    {
        // 各スキルに対応するタイマーを初期化
        foreach (var _ in _skills)
        {
            _timers.Add(0f);
        }
    }

    private void Update()
    {
        for (int i = 0; i < _skills.Count; i++)
        {
            _timers[i] += Time.deltaTime;

            if (_timers[i] >= _skills[i].interval)
            {
                Shoot(_skills[i]);
                _timers[i] = 0f;
            }
        }
    }

    private void Shoot(AutoAttackSkill skill)
    {
        GameObject bullet = Instantiate(skill.bulletPrefab, _muzzle.position, Quaternion.identity);
        Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
        rb.velocity = skill.direction.normalized * skill.speed;
    }
}
   

✅ ステップ③:スキルデータにScriptableObjectを使用する

📄 AutoAttackSkillData.cs

[CreateAssetMenu(fileName = "SkillData", menuName = "Skills/AutoAttackSkill")]
public class AutoAttackSkillData : ScriptableObject
{
    public string name;
    public GameObject bulletPrefab;
    public float interval;
    public float speed;
    public Vector2 direction;
}

📄 PlayerAutoAttack.cs

using UnityEngine;
using System.Collections.Generic;

public class PlayerAutoAttack : MonoBehaviour
{
    [SerializeField]
    private List<AutoAttackSkillData> _skills = new();

    [SerializeField]
    private Transform _muzzle;

    private List<float> _timers = new();

    private void Start()
    {
        // 各スキルに対応するタイマーを初期化
        foreach (var _ in _skills)
        {
            _timers.Add(0f);
        }
    }

    private void Update()
    {
        for (int i = 0; i < _skills.Count; i++)
        {
            _timers[i] += Time.deltaTime;

            if (_timers[i] >= _skills[i].interval)
            {
                Shoot(_skills[i]);
                _timers[i] = 0f;
            }
        }
    }

    private void Shoot(AutoAttackSkillData skill)
    {
        GameObject bullet = Instantiate(skill.bulletPrefab, _muzzle.position, Quaternion.identity);
        Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
        rb.velocity = skill.direction.normalized * skill.speed;
    }
}

🔍 補足・Tips・参考リンク


🕒 Time.deltaTime とは?

  • 各フレームにかかる実時間(秒)を表す
  • フレームレートに依存せず、正確な「時間経過処理」を行うために使用する
  • タイマー制御・アニメーション・移動・攻撃間隔の計測などに活用できる

💾 ScriptableObjectとは?

  • データだけを保持するための特殊なUnityオブジェクト。MonoBehaviourと異なり、Sceneに置かずに使える「アセット化されたデータ」。

  • スキルデータ、敵の設定、武器パラメータなどを再利用・共有しやすい

  • デザイナーや非エンジニアが Inspector 上で設定・調整可能

  • プログラムとデータの分離ができ、保守しやすい

  • 使い方例(スキルを ScriptableObject にする)

🔧 Inspector設定例(複数スキル)

  • スキル①:前方に1秒間隔で弾を発射(speed: 10)
  • スキル②:左右に2秒間隔で同時発射(direction: left/right)
  • スキル③:斜め・広範囲・低速の大ダメージ弾など

✅ 動作確認チェックリスト

  • 弾が自動で一定間隔に発射される
  • 複数スキルの弾が異なる方向・速度で発射される
  • スキルごとに独立したタイマーが動作している

📝 課題

  • 1.スキルを3つ登録し、異なる設定(方向・速度・間隔)で同時発射できるようにしよう。
  • 2.スキルに「最大発射回数(maxShots)」を設定し、使い切ったら停止(使用不可)させよう。
  • 3.自分なりにスキルをカスタマイズして遊んでみよう!
⚠️ **GitHub.com Fallback** ⚠️