Week05_Skills - M-634/unity-game-dev-tutorial GitHub Wiki
- プレイヤーが一定間隔で自動的に攻撃(弾)を撃てるようにする
- 攻撃間隔(クールタイム)の制御方法を理解する
- 複数の攻撃スキルを同時に持ち、違う方向・速度・発射間隔で発動できるようにする
- 自動攻撃システムの拡張に備えた柔軟な設計を学ぶ
- ScriptableObjectに触れてみる
スキルデータクラス作成
[System.Serializable]
public class AutoAttackSkill
{
public string name;
public GameObject bulletPrefab;
public float interval;
public float speed;
public Vector2 direction;
}
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を使用する
[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;
}
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.自分なりにスキルをカスタマイズして遊んでみよう!