ふりかえり
前回は、プレイヤーと敵の画像を設定し、ゲーム画面がぐっとにぎやかになりました!
前回の投稿はこちら↓
キャラ画像にアニメーションをつける
今回は、プレイヤーと敵にアニメーションを実装して、ゲームに動きを加えていきます!
実装するアニメーションは以下のとおりです:
- 攻撃時
- ダメージを受けたとき
- 倒されたとき
- リスポーンしたとき
- レベルアップ時
🔧アニメーションには「DOTween」を使用
今回のアニメーションには、Unityで有名なアセット**DOTween** を使用します。
DOTweenは簡単なコードで多彩なアニメーションが実現できる優れもの!
導入方法や基本的な使い方は次回の投稿で詳しく解説します。

DOTween (HOTween v2) | Animation Tools | Unity Asset Store
Use the DOTween (HOTween v2) tool from Demigiant on your next project. Find this & more animation tools on the Unity Ass...
スクリプトの実装:AnimationManager.cs
アニメーションを管理するためのスクリプトを作成します。
using UnityEngine;
using DG.Tweening; // DOTweenを使用するために追加
public class AnimationManager : MonoBehaviour
{
public Transform playerTransform; // プレイヤーのTransform
public Transform enemyTransform; // 敵のTransform
public SpriteRenderer playerSpriteRenderer; // プレイヤーのSpriteRenderer
public SpriteRenderer enemySpriteRenderer; // 敵のSpriteRenderer
public float attackDuration = 0.5f; // 攻撃アニメーションの時間
public float attackDistance = 0.5f; // 攻撃アニメーションの距離
public float damageDuration = 0.3f; // ダメージアニメーションの時間
public float shakeStrength = 1f; // シェイクの強さ
public int shakeVibrato = 100; // シェイクの振動数
public float fadeOutDuration = 1.0f; // フェードアウトの時間
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
// プレイヤーの攻撃アニメーション
public void PlayerAttackAnimation()
{
if (playerTransform != null)
{
// プレイヤーを敵の方向に少し移動させる
playerTransform.DOMove(playerTransform.position + Vector3.right * attackDistance, attackDuration / 2)
.SetEase(Ease.OutQuad)
.OnComplete(() =>
{
// 元の位置に戻る
playerTransform.DOMove(playerTransform.position - Vector3.right * attackDistance, attackDuration / 2)
.SetEase(Ease.InQuad);
});
}
}
// 敵の攻撃アニメーション
public void EnemyAttackAnimation()
{
if (enemyTransform != null)
{
// 敵をプレイヤーの方向に少し移動させる
enemyTransform.DOMove(enemyTransform.position + Vector3.left * attackDistance, attackDuration / 2)
.SetEase(Ease.OutQuad)
.OnComplete(() =>
{
// 元の位置に戻る
enemyTransform.DOMove(enemyTransform.position - Vector3.left * attackDistance, attackDuration / 2)
.SetEase(Ease.InQuad);
});
}
}
// プレイヤーのダメージアニメーション
public void PlayerDamageAnimation()
{
if (playerTransform != null)
{
// プレイヤーをシェイクさせる
playerTransform.DOShakePosition(damageDuration, shakeStrength, shakeVibrato)
.SetEase(Ease.OutQuad);
}
}
// 敵のダメージアニメーション
public void EnemyDamageAnimation()
{
if (enemyTransform != null)
{
// 敵をシェイクさせる
enemyTransform.DOShakePosition(damageDuration, shakeStrength, shakeVibrato)
.SetEase(Ease.OutQuad);
}
}
// プレイヤーのレベルアップアニメーション
public void PlayerLevelUpAnimation()
{
if (playerTransform != null)
{
// プレイヤーを少し大きくしてから元に戻す
playerTransform.DOScale(playerTransform.localScale * 2f, 0.3f)
.SetEase(Ease.OutQuad)
.OnComplete(() =>
{
playerTransform.DOScale(playerTransform.localScale / 2f, 0.3f)
.SetEase(Ease.InQuad);
});
}
}
// プレイヤーの死亡アニメーション
public void PlayerDeathAnimation()
{
if (playerSpriteRenderer != null)
{
// プレイヤーをフェードアウトさせる
playerSpriteRenderer.DOFade(0f, fadeOutDuration)
.SetEase(Ease.InQuad)
.OnComplete(() =>
{
Debug.Log("プレイヤーが消えました");
});
}
}
// 敵の死亡アニメーション
public void EnemyDeathAnimation()
{
if (enemySpriteRenderer != null)
{
// 敵をフェードアウトさせる
enemySpriteRenderer.DOFade(0f, fadeOutDuration)
.SetEase(Ease.InQuad)
.OnComplete(() =>
{
Debug.Log("敵が消えました");
});
}
}
// プレイヤーの復活アニメーション
public void PlayerReviveAnimation()
{
if (playerSpriteRenderer != null)
{
// プレイヤーをフェードインさせる
playerSpriteRenderer.DOFade(1f, fadeOutDuration)
.SetEase(Ease.OutQuad);
}
}
// 敵の復活アニメーション
public void EnemyReviveAnimation()
{
if (enemySpriteRenderer != null)
{
// 敵をフェードインさせる
enemySpriteRenderer.DOFade(1f, fadeOutDuration)
.SetEase(Ease.OutQuad);
}
}
}
プレイヤー・敵スクリプトの変更
PlayerManager.csにて:
- 攻撃時:animationManager.PlayerAttackAnimation()
- ダメージ時:PlayerDamageAnimation()
- 死亡時:PlayerDeathAnimation()
- 復活時:PlayerReviveAnimation()
- レベルアップ時:PlayerLevelUpAnimation()
EnemyManager.csにて:
- 攻撃時:EnemyAttackAnimation()
- ダメージ時:EnemyDamageAnimation()
- 死亡時:EnemyDeathAnimation()
- 復活時:EnemyReviveAnimation()
必要なタイミングでアニメーション関数を呼び出すことで、よりリッチなバトル表現が可能になります!
using UnityEngine;
public class PlayerManager : MonoBehaviour
{
public PlayerData player;
public AnimationManager animationManager; // AnimationManagerの参照を追加
void Start()
{
SpawnPlayer();
}
public void SpawnPlayer()
{
// 仮データで初期化
player = new PlayerData
{
name = "勇者",
level = 1,
maxHP = 100,
currentHP = 100,
attack = 10,
defense = 5,
exp = 0, // 初期経験値
gold = 0, // 初期お金
expToNextLevel = 10 // 次のレベルに必要な経験値
};
Debug.Log($"{player.name}が作成されました。HP:{player.currentHP}/{player.maxHP}");
}
private void SpawnNewPlayer()
{
SpawnPlayer();
if (animationManager != null)
{
animationManager.PlayerReviveAnimation();
}
}
public void Attack(EnemyManager enemyManager)
{
// 攻撃アニメーションを再生
if (animationManager != null)
{
animationManager.PlayerAttackAnimation();
}
int damage = Mathf.Max(0, player.attack - enemyManager.enemy.defense);
enemyManager.TakeDamage(damage);
Debug.Log($"{player.name}が{enemyManager.enemy.name}に{damage}ダメージ!");
}
public void TakeDamage(int damage)
{
// ダメージアニメーションを再生
if (animationManager != null)
{
animationManager.PlayerDamageAnimation();
}
player.currentHP -= damage;
if (player.currentHP <= 0)
{
player.currentHP = 0;
Debug.Log($"{player.name}は倒された!");
// 死亡アニメーションを再生
if (animationManager != null)
{
animationManager.PlayerDeathAnimation();
}
Invoke("SpawnNewPlayer", 1.0f);
}
}
public void GainRewards(int exp, int gold)
{
player.exp += exp;
player.gold += gold;
Debug.Log($"{player.name}は{exp}EXPと{gold}Gを獲得しました!");
// レベルアップのチェック
CheckLevelUp();
}
private void CheckLevelUp()
{
if (player.exp >= player.expToNextLevel)
{
LevelUp();
}
}
private void LevelUp()
{
player.level++;
player.maxHP += 20; // HPを20増加
player.currentHP = player.maxHP; // HPを全回復
player.attack += 5; // 攻撃力を5増加
player.defense += 3; // 防御力を3増加
player.expToNextLevel += 10; // 次のレベルに必要な経験値を10増加
player.exp = 0; // 経験値をリセット
// レベルアップアニメーションを再生
if (animationManager != null)
{
animationManager.PlayerLevelUpAnimation();
}
Debug.Log($"{player.name}がレベルアップ!レベル{player.level}になりました!");
Debug.Log($"HP: {player.maxHP}, 攻撃力: {player.attack}, 防御力: {player.defense}");
}
}
using UnityEngine;
public class EnemyManager : MonoBehaviour
{
public EnemyData enemy;
public PlayerManager playerManager; // PlayerManagerの参照を追加
public AnimationManager animationManager; // AnimationManagerの参照を追加
private void Start()
{
SpawnEnemy(); // 初期の敵を生成
}
private void SpawnEnemy()
{
enemy = new EnemyData
{
name = "スライム",
level = 1,
maxHP = 50,
currentHP = 50,
attack = 8,
defense = 2,
expReward = 10, // 経験値報酬を設定
goldReward = 5 // お金報酬を設定
};
Debug.Log($"{enemy.name} が出現しました。HP: {enemy.currentHP}/{enemy.maxHP}");
}
private void SpawnNewEnemy()
{
// 新しい敵を生成
SpawnEnemy();
// 復活アニメーションを再生
if (animationManager != null)
{
animationManager.EnemyReviveAnimation();
}
}
public void Attack(PlayerManager playerManager)
{
// 攻撃アニメーションを再生
if (animationManager != null)
{
animationManager.EnemyAttackAnimation();
}
int damage = Mathf.Max(0, enemy.attack - playerManager.player.defense);
playerManager.TakeDamage(damage);
Debug.Log($"{enemy.name}が{playerManager.player.name}に{damage}ダメージ!");
}
public void TakeDamage(int damage)
{
// ダメージアニメーションを再生
if (animationManager != null)
{
animationManager.EnemyDamageAnimation();
}
enemy.currentHP -= damage;
if (enemy.currentHP <= 0)
{
enemy.currentHP = 0;
Debug.Log($"{enemy.name}を倒した!");
// 死亡アニメーションを再生
if (animationManager != null)
{
animationManager.EnemyDeathAnimation();
}
// プレイヤーにEXPとGを与える
if (playerManager != null)
{
playerManager.GainRewards(enemy.expReward, enemy.goldReward);
}
Invoke("SpawnNewEnemy", 1.0f); // 新しい敵を生成
}
}
}
Unityでの設定
- DOTweenの導入(※次回説明予定)
- Hierarchyで「Create Empty」からオブジェクトを作成し、 AnimationManager.cs をアタッチ
- Inspectorで以下を設定:
- playerTransform → PlayerImageオブジェクト
- enemyTransform → EnemyImageオブジェクト
- playerSpriteRenderer / enemySpriteRenderer → 各SpriteRenderer
- PlayerManager・EnemyManagerにも AnimationManager をアサイン

動作確認
ゲームを開始して「Player Attack」ボタンをクリックすると、
キャラクターが動いたり、ダメージアニメーションが表示されるようになります!
動きが加わると、一気にゲーム感がアップしますね!
まとめ
今回は、DOTweenを使ってキャラ画像にアニメーションを追加しました!
動きがあるだけで、ゲームのクオリティがぐっと高まります!
次回予告
次回は、効果音(SE)の実装に挑戦します!
アニメーションと音が組み合わさると、さらに臨場感が出てきますよ!
お楽しみに!




コメント