
前回で、敵とターンを回して戦えるようになりました。でも、カードを敵の上で離しても、HPのゲージと数字が変わるだけで、なんだか手応えがありません・・・。今回は、カードが敵へ飛んでいき、当たったら敵が白く光ってのけぞり、数字と火花が飛び、画面が揺れる「攻撃の手応え」を作ってみたいと思います!
- シリーズの目次:デッキ構築カードゲームの作り方
- 前回:#9 ターンの流れを作ろう
今回作るもの
- 使ったカードが、ねらった相手へ飛んでいく
- 当たったら、敵が白く光って、のけぞって戻る
- ダメージの数字が飛び出して消える(大きいダメージほど大きな文字)
- 火花のパーティクル
- ほんの一瞬だけ時間を止める(ヒットストップ)と、画面の揺れ
| スクリプト | 役割 | 付ける場所 |
|---|---|---|
| CardFly | 使ったカードを相手へ飛ばす | Card(プレハブ) |
| HitReaction | 白く光る・のけぞる。数字や火花なども呼ぶ | Enemy(プレハブ) |
| DamagePopup | ダメージの数字を飛ばして消す | DamagePopup(プレハブ) |
| EffectSpawner | 数字と火花を出す | Effects(新しく作る空のオブジェクト) |
| HitStop | 一瞬だけ時間を止める | Effects |
| ScreenShake | 戦いの画面(Stage)を揺らす | Effects |
| Deck・CardDrag・PlayZone(直す) | カードを飛ばしてから効果を出す | - |
| Fighter(直す) | HPが減ったら HitReaction を呼ぶ | - |
スライムちゃんが攻撃を受けたとき・防御や回復のときの演出は、次の#11で作ります。
なぜ演出が要るの?
まずは、今の状態(#9まで)で「定規でペシッ」と「ホチキスでパチン」を使ってみたのが下図です。

ルールとしては正しく動いていますが、ゲージを見ていないと「当たったのか」「どれぐらい効いたのか」が分かりません。6ダメージのカードも12ダメージのカードも、見た目は同じです。
今回は、当たった瞬間に次のことを一度に起こします。
- カードが飛んでいく:どの敵に使ったかが分かる
- 白く光って、のけぞる:当たったことが分かる
- 数字が飛び出す:どれぐらい効いたかが分かる。大きいダメージほど大きな文字にする
- 火花・ヒットストップ・揺れ:「重さ」が伝わる。揺れはダメージが大きいほど強くする
1つ1つは0.1〜0.3秒ぐらいの短い動きです。でも、全部が同じ瞬間に重なると、同じ6ダメージでもぐっと気持ちよくなります。
フェアリーゲームの「手応え」は、1つの派手な演出よりも、小さな反応をいくつも重ねると出てくるよ!
前回の続きから
前回の最後の状態から始めます。火花の粒の絵は、素材のzipを入れ直すと入ります。
- DeckBuildingAssets.zip
DeckBuilding/Sprites/Effects/fx_spark.png(火花の粒。白い4本の光。色はパーティクルの設定で付ける)- 自分で入れた場合は、Sprite Mode:Singleにして Apply
パーティクルをUIの手前に出すために、Sorting Layerを1つ足しておきます。
- Edit>Project Settings>Tags and Layers を開く
- Sorting Layersの「+」を押して、名前をEffectにする
- Defaultより下(後ろ)に並んでいればOK。下に並んでいるほど手前に描かれます


カードを敵へ飛ばそう(CardFly)
今は、カードを離した瞬間にカードが消えて、効果が出ています。これを「カードが相手まで飛んでいって、当たったら効果が出る」順番に変えます。
- DeckBuilding/Scriptsに「CardFly」スクリプトを作る
using System.Collections;
using UnityEngine;
// 使ったカードを、ねらった相手へ飛ばす(小さくなりながら、だんだん速く)
public class CardFly : MonoBehaviour
{
[SerializeField] private float flySeconds = 0.2f; // 飛んでいく時間
[SerializeField] private float endScale = 0.3f; // 当たるときの大きさ
public IEnumerator FlyTo(Vector3 targetPosition)
{
transform.SetAsLastSibling(); // 手札のほかのカードより手前に出す
Vector3 startPosition = transform.position;
Vector3 startScale = transform.localScale;
Quaternion startRotation = transform.localRotation;
float time = 0f;
while (time < flySeconds)
{
time += Time.deltaTime;
float t = Mathf.Clamp01(time / flySeconds);
float eased = t * t; // 最初はゆっくり、だんだん速く(勢いよく当たる)
transform.position = Vector3.Lerp(startPosition, targetPosition, eased);
transform.localScale = Vector3.Lerp(startScale, Vector3.one * endScale, eased);
transform.localRotation = Quaternion.Lerp(startRotation, Quaternion.Euler(0f, 0f, -30f), eased);
yield return null;
}
}
}
FlyToはコルーチン- 呼ぶ側が
yield return StartCoroutine(…)で、飛び終わるまで待てるようにしています
- 呼ぶ側が
eased = t * t- 0→1の進み方を「最初はゆっくり、後半で速く」にする計算です。そのまま
tを使うと同じ速さで進むので、ぶつかる勢いが出ません
- 0→1の進み方を「最初はゆっくり、後半で速く」にする計算です。そのまま
- 位置・大きさ・角度を、同じ
easedで一緒に変える- 小さくなりながら少し傾いて、奥へ飛んでいくように見えます
作ったら、Prefabs/Cardを開いて、Add Component>CardFlyを付けます。


Deck・CardDrag・PlayZoneを直す
カードを飛ばす間は、カードを消さずに残しておく必要があります。3つのスクリプトを直します。
まずDeckのUseCardから、カードを消す1行を消します(手札のリストから外すのはそのまま)。
handLayout.Remove((RectTransform)view.transform);
Destroy(view.gameObject); // ★#10 この行を消す(カードは PlayZone が飛ばしてから消す)
UpdateCounts();
CardDragのOnEndDragは、使ったカードがマウスに反応しないように、blocksRaycasts = trueをifの中へ移します。
public void OnEndDrag(PointerEventData eventData)
{
if (!isUsed)
{
canvasGroup.blocksRaycasts = true; // ★#10 使ったカードは、飛んでいる間もマウスに反応させない
handLayout.ClearHeld(rectTransform); // 使わなかったら、手札の並びに戻す
}
}
最後にPlayZoneです。OnDropの最後で、効果を出していたforeachを新しいコルーチンに移します。
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
- 一番上に
using System.Collections;を足す(コルーチンを使うため)
card.MarkUsed();
energy.Pay(data.cost); // ★#7 エネルギーを払う
deck.UseCard(card.View, targetName);
StartCoroutine(PlayCard(card, data, enemy)); // ★#10 飛ばしてから効果を出す
}
// ★#10 カードを相手へ飛ばして、当たったら効果を出す
private IEnumerator PlayCard(CardDrag card, CardData data, Fighter enemy)
{
Fighter target = enemy != null ? enemy : player; // 攻撃は敵へ、ほかはスライムちゃんへ
CardFly fly = card.GetComponent<CardFly>();
yield return StartCoroutine(fly.FlyTo(target.transform.position));
Destroy(card.gameObject);
// ★#7 カードの効果を、上から順番に出す
foreach (CardEffect effect in data.effects)
{
effect.Apply(player, enemy, deck, energy);
}
}
OnDropのdeck.UseCard(…)より下(foreachの部分)を、StartCoroutine(PlayCard(…))の1行に置きかえる- 攻撃のカードは敵へ、防御や回復のカードはスライムちゃんへ飛んでいく
- 飛び終わってからカードを消して、効果を出す
コルーチンはPlayZoneで動かしています。カードの側(CardFly)で動かすと、カードをDestroyした瞬間にコルーチンも止まってしまい、効果が出ません。消すものとは別のオブジェクトで待つのがポイントです。


白く光ってのけぞる(HitReaction)
次は、当たった敵の反応です。
- 白く光る:0.08秒だけ、敵の形のまま真っ白にする
- のけぞる:当たった向き(右)に40だけ押されて、0.25秒で元の位置に戻る
白く光らせるマテリアル
UIのImageのColorは「絵の色に掛け算」なので、白(255,255,255)にしても元の絵のままで、白くは光りません。そこで、絵の形だけを使って1色で塗るマテリアルを使います。
- Projectウインドで DeckBuilding/Effects フォルダを作る
- Effectsフォルダで右クリック>Create>Material、名前をWhiteFlash
- Shader:GUI/Text Shader


Enemyのプレハブに光る絵を重ねる
- Prefabs/Enemyを開く
- Enemyの子にFlash(UI (Canvas)>Image)
- Enemyの子の一番上に移す(体の上、ゲージや予告の下に描かれる)
- アンカー:stretch-stretch、Left・Top・Right・Bottom:0
- Source Image:enemy_tinrobot(仮。Preserve Aspectの項目を出すため)
- Material:WhiteFlash
- Color:白、Alpha:0(ふだんは見えない)
- Raycast Targetのチェックを外す
- Preserve Aspectにチェック(体の絵と同じ)


Source Imageに入れた絵は仮です。敵の絵はデータから入るので、再生したらスクリプトで体と同じ絵に入れかえます(Source Imageが空だと、Preserve Aspectの項目がInspectorに出てきません)。
- DeckBuilding/Scriptsに「HitReaction」スクリプトを作る
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
// ダメージを受けたときの反応:白く光って、のけぞって戻る
[RequireComponent(typeof(Image))]
public class HitReaction : MonoBehaviour
{
[SerializeField] private Image flashImage; // 体の上に重ねた、白く光らせる絵
[SerializeField] private float flashSeconds = 0.08f; // 白く光っている時間
[SerializeField] private Vector2 knockback = new Vector2(40f, 0f); // のけぞる向きと距離
[SerializeField] private float recoverSeconds = 0.25f; // 元の位置に戻るまでの時間
private RectTransform body;
private Vector2 startPosition;
private void Start()
{
body = (RectTransform)transform;
startPosition = body.anchoredPosition;
flashImage.sprite = GetComponent<Image>().sprite; // 体と同じ形で光らせる
flashImage.color = Color.clear;
}
// Fighter がダメージを受けたときに呼ぶ
public void Play(int damage)
{
StopAllCoroutines();
StartCoroutine(FlashAndKnockback());
}
private IEnumerator FlashAndKnockback()
{
// 白く光って、後ろへ押される
flashImage.color = Color.white;
body.anchoredPosition = startPosition + knockback;
yield return new WaitForSeconds(flashSeconds);
flashImage.color = Color.clear;
// 元の位置へ戻る
float time = 0f;
while (time < recoverSeconds)
{
time += Time.deltaTime;
body.anchoredPosition = Vector2.Lerp(startPosition + knockback, startPosition, time / recoverSeconds);
yield return null;
}
body.anchoredPosition = startPosition;
}
}
Startで体の絵をflashImageに入れる- 敵の絵は、EnemyParty が敵を作った直後の
Setupで入ります。Startはそのあとに呼ばれるので、ブリキロボにもびっくり箱にも、正しい形が入ります
- 敵の絵は、EnemyParty が敵を作った直後の
StopAllCoroutines()- ハサミのように続けて当たったとき、前の動きを止めてから、もう一度最初から光らせます
- 光るのは一瞬で、戻るのはゆっくり
- 「バシッ」と押されて「スーッ」と戻ると、当たった感じが出ます
作ったら、プレハブのEnemy(一番上)に Add Component>HitReactionを付けて、Flash ImageにFlashを入れます。


Fighterから呼ぶ
HPが減ったときに、HitReactionを呼びます。Fighterに足します。
private int block; // 防御:ダメージを先に受けとめてくれる
private HitReaction hitReaction; // ★#10 ダメージを受けたときの反応(付いていなければ null)
private void Awake()
{
hp = maxHp;
hitReaction = GetComponent<HitReaction>(); // ★#10
}
Debug.Log($"{fighterName}に{amount}ダメージ(防御で{blocked}防いだ) HP {hp}/{maxHp}");
// ★#10 HP が減ったら、反応を出す
if (damage > 0 && hitReaction != null)
{
hitReaction.Play(damage);
}
}
TakeDamageのDebug.Logの下に足す- スライムちゃん(PlayerArea)にはまだHitReactionを付けていないので、
hitReactionはnullになり、何も起きません(#11で付けます) - 防御で全部防いだとき(
damageが0)も反応しません。防いだときの演出は#11で作ります


ダメージの数字を出そう(DamagePopup)
次は、当たったところから飛び出す数字です。
数字を出す場所(PopupLayer)
数字は、敵やカードより手前に出したいので、Canvasの一番下(一番手前)に専用の入れ物を作ります。
- Canvasの子にPopupLayer(Create Empty)
- Canvasの子の一番下に置く
- アンカー:stretch-stretch、Left・Top・Right・Bottom:0
数字のプレハブ
- DeckBuilding/Scriptsに「DamagePopup」スクリプトを作る
using TMPro;
using UnityEngine;
// ダメージの数字:大きく出て、放物線を描いて飛び、消える
[RequireComponent(typeof(TextMeshProUGUI))]
public class DamagePopup : MonoBehaviour
{
[SerializeField] private float lifeSeconds = 0.8f; // 消えるまでの時間
[SerializeField] private float jumpSpeed = 600f; // 上へ飛び出す速さ
[SerializeField] private float gravity = 1800f; // 下へ引っぱる強さ
private TextMeshProUGUI text;
private RectTransform rectTransform;
private Vector2 velocity;
private float time;
public void Setup(int damage)
{
text = GetComponent<TextMeshProUGUI>();
rectTransform = (RectTransform)transform;
text.text = damage.ToString();
text.fontSize = Mathf.Min(60f + damage * 4f, 140f); // 大きいダメージほど大きな文字に
velocity = new Vector2(Random.Range(-150f, 150f), jumpSpeed);
}
private void Update()
{
time += Time.deltaTime;
float t = time / lifeSeconds;
// 放物線:上へ飛び出して、重力で落ちてくる
velocity.y -= gravity * Time.deltaTime;
rectTransform.anchoredPosition += velocity * Time.deltaTime;
// 出た瞬間だけ大きく、後半で透明に
rectTransform.localScale = Vector3.one * Mathf.Lerp(1.8f, 1f, t / 0.15f);
text.alpha = Mathf.InverseLerp(1f, 0.6f, t);
if (time >= lifeSeconds)
{
Destroy(gameObject);
}
}
}
- 文字の大きさ:
60 + ダメージ×4(上限140)- 定規の6なら84、ホチキスの12なら108。数字の大きさでダメージの差が伝わるようにしています
- 動き:上向きの速さ(
jumpSpeed)で飛び出して、毎フレームgravityで下向きに引っぱる- 横の速さを
Random.Rangeで少しずつ変えているので、ハサミのように続けて当たっても数字が重なりません
- 横の速さを
- 大きさ:出た瞬間は1.8倍で、0.15秒で1倍に
- 透明度:
Mathf.InverseLerp(1f, 0.6f, t)で、残り4割の時間で1→0にInverseLerp(a, b, v)は「vがaからbのどのあたりか」を0〜1で返します。aとbを逆に書くと、だんだん減る値になります
プレハブを作ります。
- PopupLayerの子にDamagePopup(UI (Canvas)>Text – TextMeshPro)
- Width:300、Height:160
- テキスト:6、Font Size:84、Font Style:B、Color:#E8433A、Alignment:中央
- Text Wrapping Mode:No Wrap(折り返さない)、Raycast Targetのチェックを外す
- Add Component>DamagePopup
- Prefabsフォルダへドラッグしてプレハブにして、Hierarchyからは消す


数字を出す(EffectSpawner)
数字や火花を「どこに・何を出すか」を1か所にまとめます。
- DeckBuilding/Scriptsに「EffectSpawner」スクリプトを作る
using UnityEngine;
// ダメージの数字や火花を、指定した場所に出す
public class EffectSpawner : MonoBehaviour
{
[SerializeField] private DamagePopup damagePopupPrefab;
[SerializeField] private RectTransform popupLayer; // 数字を出す親(Canvas の一番手前)
[SerializeField] private ParticleSystem sparksPrefab;
public void ShowDamage(int damage, Vector3 position)
{
DamagePopup popup = Instantiate(damagePopupPrefab, popupLayer);
popup.transform.position = position;
popup.Setup(damage);
}
public void PlaySparks(Vector3 position)
{
// 火花は出し終わったら自分で消える(Stop Action:Destroy)
Instantiate(sparksPrefab, position, Quaternion.identity);
}
}
ShowDamage:PopupLayerの子に数字を作って、敵と同じ位置に置くtransform.position(ワールドの位置)でそろえているので、親がちがっても同じ場所に出ます
PlaySparks:火花は次の節で作ります。先に書いておくだけでOK
- HierarchyにEffects(Create Empty)を作って、Add Component>EffectSpawner
- Damage Popup Prefab:Prefabs/DamagePopup
- Popup Layer:PopupLayer
- Sparks Prefab:次の節で入れる
HitReactionから呼びます。HitReactionに足します。
private RectTransform body;
private Vector2 startPosition;
private EffectSpawner effectSpawner; // ★#10 数字と火花を出す
flashImage.color = Color.clear;
effectSpawner = FindFirstObjectByType<EffectSpawner>(); // ★#10
}
public void Play(int damage)
{
StopAllCoroutines();
StartCoroutine(FlashAndKnockback());
effectSpawner.ShowDamage(damage, transform.position); // ★#10 数字
}
- 敵はプレハブから作るので、シーンのEffectsはInspectorで入れられません。
FindFirstObjectByTypeでシーンから探します(#7のCardViewでEnergyを探したのと同じです)


火花のパーティクル
当たったところに、オレンジの火花を散らします。パーティクルの基本は12-4 パーティクルで演出しよう:Particle Systemの基本で紹介しています。
- Hierarchyで右クリック>Effects>Particle System、名前をHitSparks
- 下の表のとおりに設定する
| モジュール | 項目:値 |
|---|---|
| Main | Duration:0.5、Looping:チェックなし |
| Start Lifetime:Random Between Two Constants 0.25〜0.45 | |
| Start Speed:Random Between Two Constants 6〜12 | |
| Start Size:Random Between Two Constants 0.3〜0.6 | |
| Start Rotation:Random Between Two Constants 0〜360 | |
| Start Color:Random Between Two Colors #FFE066・#FF8A3D | |
| Gravity Modifier:1、Simulation Space:World、Stop Action:Destroy | |
| Emission | Rate over Time:0、Burstsの「+」で Time:0・Count:18 |
| Shape | Shape:Circle、Radius:0.1 |
| Size over Lifetime | チェックを入れて、Sizeのカーブを「1から0へ下がる」形に |
| Texture Sheet Animation | チェックを入れて、Mode:Sprites、Spriteに fx_spark |
| Renderer | Material:Sprite-Unlit-Default、Sorting Layer:Effect |




- 大きさと速さの単位は、Canvasの数字(1920×1080)ではなくワールドの単位です
- このシーンのカメラ(Orthographic Size:5)では、画面の縦が10、1がCanvasの約108に当たります。Start Speed 6〜12は、1秒に650〜1300ぐらい飛ぶ速さです
- Sorting Layer:Effect で、UIより手前に描かれます
- Materialは、2DのURPで確実に表示されるスプライト用の Sprite-Unlit-Default にしています
- 選ぶときは、Materialの右の丸いボタンを押して「Sprite-Unlit-Default」を検索
設定できたら、HitSparksをPrefabsフォルダへドラッグしてプレハブにして、Hierarchyからは消します。EffectsのSparks Prefabに、Prefabs/HitSparksを入れます。
HitReactionのPlayに1行足します。
effectSpawner.ShowDamage(damage, transform.position); // ★#10 数字
effectSpawner.PlaySparks(transform.position); // ★#10 火花


火花が見えないときは、RendererのSorting LayerがEffectになっているか確かめましょう。Defaultのままだと、Canvas(背景)の後ろに隠れてしまいます。ピンク色の四角になるときは、Materialが合っていません。
ヒットストップと画面の揺れ
最後に、当たった瞬間の「重さ」を足します。
- ヒットストップ:当たった瞬間、0.06秒だけ時間を止める。格闘ゲームなどでおなじみの「バシッ」と止まる感じ
- 画面の揺れ:戦いの画面(Stage)を揺らす。ダメージが大きいほど強く
HitStop
- DeckBuilding/Scriptsに「HitStop」スクリプトを作る
using System.Collections;
using UnityEngine;
// 当たった瞬間に、ほんの少しだけ時間を止める
public class HitStop : MonoBehaviour
{
public void Play(float seconds)
{
StopAllCoroutines();
StartCoroutine(Stop(seconds));
}
private IEnumerator Stop(float seconds)
{
Time.timeScale = 0f;
// timeScale が 0 の間も進む unscaledDeltaTime で数える
float time = 0f;
while (time < seconds)
{
time += Time.unscaledDeltaTime;
yield return null;
}
Time.timeScale = 1f;
}
}
Time.timeScale = 0fで、ゲームの時間が止まるTime.deltaTimeが0になるので、deltaTimeで動いているもの(カード・数字・のけぞり・パーティクル)が全部止まります
- 止まっている間の時間は、
Time.unscaledDeltaTimeで数えるTime.deltaTimeで数えると、0のまま増えないので、いつまでも時間が戻りません
ScreenShake
- DeckBuilding/Scriptsに「ScreenShake」スクリプトを作る
using UnityEngine;
// 戦いの画面(Stage)を揺らす。ダメージが大きいほど強く
public class ScreenShake : MonoBehaviour
{
[SerializeField] private RectTransform stage;
[SerializeField] private float shakeSeconds = 0.25f; // 揺れている時間
[SerializeField] private float strengthPerDamage = 2f; // ダメージ1あたりの揺れの幅
[SerializeField] private float maxStrength = 30f; // 揺れの幅の上限
private Vector2 startPosition;
private float strength;
private float timeLeft;
private void Start()
{
startPosition = stage.anchoredPosition;
}
public void Play(int damage)
{
strength = Mathf.Min(damage * strengthPerDamage, maxStrength);
timeLeft = shakeSeconds;
}
private void Update()
{
if (timeLeft <= 0f)
{
return;
}
// ヒットストップ中も揺れるように、unscaledDeltaTime で減らす
timeLeft -= Time.unscaledDeltaTime;
if (timeLeft <= 0f)
{
stage.anchoredPosition = startPosition;
return;
}
float power = strength * (timeLeft / shakeSeconds); // だんだん弱く
stage.anchoredPosition = startPosition + Random.insideUnitCircle * power;
}
}
- 揺れの幅:
ダメージ×2(上限30)- 定規の6なら12、ホチキスの12なら24。重いカードほど強く揺れます
Random.insideUnitCircle:半径1の円の中のランダムな点。これに幅を掛けて、毎フレームちがう方向へずらします- 揺らすのはStageだけ
- 手札(HandArea)やエネルギーなどのHudは揺らさないので、揺れていてもカードを操作しやすいままです
- 揺れは
unscaledDeltaTimeで数えるので、ヒットストップで止まっている間も揺れ続けます
- 止まる(
Time.deltaTime):飛んでいるカード、敵ののけぞり、数字、火花、手札の動き - 止まらない(
Time.unscaledDeltaTime):画面の揺れ、ヒットストップ自身の時間 - 「全部止まっているのに、画面だけがブルッと震える」ので、止まった瞬間が強く感じられます
どちらもEffectsに付けます。
- Effectsに Add Component>HitStop
- Effectsに Add Component>ScreenShake、StageにCanvas>Stageを入れる


HitReactionに足します。これでHitReactionは完成です。
[SerializeField] private float recoverSeconds = 0.25f; // 元の位置に戻るまでの時間
[SerializeField] private float hitStopSeconds = 0.06f; // ★#10 時間を止める長さ
private EffectSpawner effectSpawner; // ★#10 数字と火花を出す
private HitStop hitStop; // ★#10
private ScreenShake screenShake; // ★#10
effectSpawner = FindFirstObjectByType<EffectSpawner>(); // ★#10
hitStop = FindFirstObjectByType<HitStop>(); // ★#10
screenShake = FindFirstObjectByType<ScreenShake>(); // ★#10
}
effectSpawner.ShowDamage(damage, transform.position); // ★#10 数字
effectSpawner.PlaySparks(transform.position); // ★#10 火花
hitStop.Play(hitStopSeconds); // ★#10 一瞬止める
screenShake.Play(damage); // ★#10 揺らす
}



0.06秒って、ほとんど見えない長さですよね・・・本当に効くんですか?



見えないぐらいがちょうどいいの!長くすると「引っかかった」ように感じるから、0.03〜0.1秒ぐらいで試してみてね
動かして確認!
再生して、「定規でペシッ」と「ホチキスでパチン」を敵に使ってみましょう。ホチキスは最初のデッキに入っていないので、確かめるときだけDeckのStarting Deckに足してください(#7と同じです)。


#10の動作確認
- カードを敵の上で離すと、カードが小さくなりながら敵へ飛んでいく
- 防御や回復のカードは、スライムちゃんへ飛んでいく
- 当たった瞬間に、敵が白く光って右へのけぞり、元の位置へ戻る
- 赤い数字が飛び出して、放物線を描いて消える。12の方が6より大きい
- オレンジの火花が散って、自然に消える(Hierarchyに HitSparks(Clone) が残り続けない)
- 画面(Stage)が揺れる。手札とエネルギーは揺れない。12の方が6より強く揺れる



同じ6ダメージなのに、ぜんぜん気持ちよさが違いますね!
あとがき
今回は、攻撃が当たったときに、カードが飛んで、敵が光ってのけぞり、数字と火花が飛んで、画面が揺れるようにしました。1つ1つは短い動きですが、重ねると「効いた!」という手応えがしっかり出ますね。次回は、スライムちゃんが攻撃を受けたとき・防御で防いだとき・回復したときの演出を作りたいと思います!
コメント
コメント一覧 (1件)
[…] 前回:#10 攻撃の手応えを作ろう […]