Week07_LevelUp - M-634/unity-game-dev-tutorial GitHub Wiki
- 敵を倒すと経験値アイテム(Gem)が出現
- プレイヤーが近づくと自動で吸収され、経験値が加算される
- 経験値がたまるとレベルアップ
- レベルに応じてスキル性能(発射間隔や速度)が強化される
- DOTweenを使って吸収演出をなめらかにする
DOTween は Unity 向けのアニメーション/Tween ライブラリで、
「移動・回転・色変更などをスムーズに実装できる」強力なツールです。
今回は経験値アイテムがプレイヤーに吸い寄せられる演出に使用します。
- Unity メニューから
Tools > Demigiant > DOTween Utility Panel
を選択 - パネルが開いたら、右上の 「Setup DOTween...」 をクリック
- Unity が自動でライブラリを初期化・設定してくれます
🔸 パッケージ導入時に
Assets > Plugins > DOTween
フォルダが生成されます
🔸 もしメニューが表示されない場合は 公式サイト から再取得も可能
DOTween を使うスクリプトの先頭で、以下のように名前空間を追加してください。
using DG.Tweening;
transform.DOMove(_player.position, 0.5f).SetEase(Ease.InOutSine);
-
DOMove()
:オブジェクトを指定位置に一定時間で移動させる -
SetEase()
:加速や減速のカーブを設定(自然な動きになる)
🔗 参考リンク
-
Unityメニュー
Tools > Demigiant > DOTween Utility Panel
を開く -
「Setup DOTween...」を実行(初回のみ)
-
スクリプト冒頭に
using DG.Tweening;
を追記
using UnityEngine;
using DG.Tweening;
public class ExpPickup : MonoBehaviour
{
[SerializeField] private int _expValue = 5;
private Transform _player;
private bool _isMoving = false;
private void Start()
{
_player = GameObject.FindGameObjectWithTag("Player")?.transform;
}
private void Update()
{
if (_isMoving || _player == null) return;
float distance = Vector2.Distance(transform.position, _player.position);
if (distance < 3f)
{
_isMoving = true;
transform.DOMove(_player.position, 0.5f).SetEase(Ease.InOutSine);
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
LevelManager levelManager = FindObjectOfType<LevelManager>();
levelManager?.AddExp(_expValue);
Destroy(gameObject);
}
}
}
using UnityEngine;
public class EnemyDamage : MonoBehaviour
{
[SerializeField] private int _hp = 3;
[SerializeField] private GameObject _expPickupPrefab;
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Bullet"))
{
_hp--;
if (_hp <= 0)
{
Instantiate(_expPickupPrefab, transform.position, Quaternion.identity);
Destroy(gameObject);
}
}
}
}
レベル情報はゲーム中1つだけ存在し、常にどこからでも参照される必要があります。
このようなケースに適しているのが Singleton(シングルトン)パターン です。
- インスタンスが1つだけ存在することを保証する仕組み
- 他のスクリプトから
LevelManager.Instance
のようにして簡単にアクセスできる - UIやスコア、ゲームマネージャーなどでもよく使われるパターン
using UnityEngine;
using TMPro;
public class LevelManager : MonoBehaviour
{
[SerializeField] private TextMeshProUGUI _levelText;
private int _level = 1;
private int _exp = 0;
private int _expToNext = 10;
public int CurrentLevel => _level;
public void AddExp(int amount)
{
_exp += amount;
if (_exp >= _expToNext)
{
LevelUp();
}
UpdateUI();
}
private void LevelUp()
{
_level++;
_exp = 0;
_expToNext += 10;
Debug.Log("Level Up! 現在のレベル: " + _level);
}
private void UpdateUI()
{
if (_levelText != null)
{
_levelText.text = $"Lv. {_level}";
}
}
}
using UnityEngine;
using System.Collections.Generic;
[CreateAssetMenu(fileName = "NewSkill", menuName = "Skills/AutoAttackSkill")]
public class AutoAttackSkillData : ScriptableObject
{
public GameObject bulletPrefab;
public List<float> intervalPerLevel;
public List<float> speedPerLevel;
public Vector2 direction = Vector2.right;
public float GetInterval(int level)
{
return intervalPerLevel[Mathf.Clamp(level - 1, 0, intervalPerLevel.Count - 1)];
}
public float GetSpeed(int level)
{
return speedPerLevel[Mathf.Clamp(level - 1, 0, speedPerLevel.Count - 1)];
}
}
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 LevelManager _levelManager;
private void Start()
{
_levelManager = FindObjectOfType<LevelManager>();
foreach (var _ in _skills)
{
_timers.Add(0f);
}
}
private void Update()
{
int currentLevel = _levelManager?.CurrentLevel ?? 1;
for (int i = 0; i < _skills.Count; i++)
{
_timers[i] += Time.deltaTime;
if (_timers[i] >= _skills[i].GetInterval(currentLevel))
{
Shoot(_skills[i], currentLevel);
_timers[i] = 0f;
}
}
}
private void Shoot(AutoAttackSkillData skill, int level)
{
GameObject bullet = Instantiate(skill.bulletPrefab, _muzzle.position, Quaternion.identity);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
rb.velocity = skill.direction.normalized * skill.GetSpeed(level);
}
}
- ✅ 敵を倒すと宝石型の経験値アイテムが出現する
- ✅ プレイヤーが近づくと DOTween で吸い寄せられるように動く
- ✅ 接触すると経験値が加算され、アイテムは消える
- ✅ レベルアップ時に Console に「Level Up!」が出力される
- ✅ 発射間隔または弾速がレベルに応じて変化する
- ✅ 画面上部に現在の Lv が表示されている
- 経験値アイテムを吸収してレベルアップできるようにしよう
- レベルアップ時にスキルの性能が変化するように調整しよう
- DOTween を使った吸収演出をなめらかに実装しよう