個人ゲーム開発日報|敵を倒してダイヤをゲット

ゲーム開発
スポンサーリンク

前回は、敵が落としたコインを右上の数字に加算する処理を実装しました。

個人ゲーム開発日報|コインの加算の実装
今回は、敵が落としたコインを右上の数字に加算する処理を実装したいと思います。

ライフの設置とダイヤモンドの実装

今回は敵のライフを設定し、ダメージがライフを超えたら敵が消えてダイヤモンドを落とす処理を実装します。実装したいことは以下です。

  • 敵のライフを設定する。今回は10にしておく。
  • ダメージがライフを超えたら敵が一瞬消えて、ダイヤモンドを落とす。

実装コード

前回のコードを変更します。

using UnityEngine;
using DG.Tweening;
using TMPro;
using System.Collections;

public class ClickDamageHandler : MonoBehaviour
{
    public GameObject coinPrefab; // コインのプレハブ
    public GameObject diamondPrefab; // ダイヤのプレハブ
    public Transform coinSpawnPoint; // コインが飛び出す位置
    public TMP_Text coinCountText; // コイン獲得数を表示するTextMeshProUGUI
    private int coinCount = 0; // 獲得したコインの数
    private int damageCount = 0; // ダメージ数のカウント
    private int enemyLife = 10; // 敵のライフ
    private Vector3 originalPosition; // オブジェクトの元の位置
    private bool isAnimating = false; // アニメーション中かどうかを示すフラグ

    private SpriteRenderer spriteRenderer; // スプライトレンダラー

    void Start()
    {
        // オブジェクトの元の位置を保存
        originalPosition = transform.localPosition;
        spriteRenderer = GetComponent<SpriteRenderer>(); // スプライトレンダラーを取得
        UpdateCoinCountText(); // 初期表示の更新
    }

    void OnMouseDown()
    {
        if (!isAnimating)
        {
            damageCount++; // ダメージ数を増加
            LogDamage(); // ダメージ数をコンソールに表示
            ShakeObject(); // オブジェクトを揺らす
            SpawnCoin(); // コインを生成して飛ばす
            enemyLife--; // 敵のライフを減少
            if (enemyLife <= 0)
            {
                DropDiamondAndRespawnEnemy(); // ダイヤを生成し、敵をリスポーン
            }
        }
    }

    void LogDamage()
    {
        Debug.Log("Damage: " + damageCount); // コンソールにダメージ数を表示
    }

    void ShakeObject()
    {
        // アニメーション中フラグを設定
        isAnimating = true;

        // 左にもっと動かしてから元の位置に戻す
        transform.DOLocalMoveX(originalPosition.x - 0.2f, 0.05f) // 移動の幅を0.2fに設定
            .SetLoops(2, LoopType.Yoyo)
            .OnComplete(() => isAnimating = false); // アニメーションが終了したらフラグをリセット
    }

    void SpawnCoin()
    {
        // コインを生成
        GameObject coin = Instantiate(coinPrefab, coinSpawnPoint.position, Quaternion.identity);

        // コインを敵キャラクターより上に表示
        coin.GetComponent<SpriteRenderer>().sortingOrder = 10;

        // コインに飛び出すアニメーションを適用
        float dropHeight = Random.Range(-2.0f, -4.0f); // 落下先を2倍に伸ばす
        Vector3 peakPosition = new Vector3(
            coinSpawnPoint.position.x,
            coinSpawnPoint.position.y + 1.0f, // 一度上に上がる
            coinSpawnPoint.position.z
        );
        Vector3 targetPosition = new Vector3(
            coinSpawnPoint.position.x + Random.Range(-1.0f, 1.0f), // 横の範囲を広げる
            coinSpawnPoint.position.y + dropHeight,
            coinSpawnPoint.position.z
        );

        Sequence coinSequence = DOTween.Sequence();
        coinSequence.Append(coin.transform.DOMove(peakPosition, 0.15f).SetEase(Ease.OutQuad)) // 上に上がる動きを2倍速に
                    .Append(coin.transform.DOMove(targetPosition, 0.25f).SetEase(Ease.InQuad)) // 下に落ちる動きを2倍速に
                    .OnComplete(() => StartCoroutine(CoinLifetime(coin))); // アニメーション完了時にコインのライフタイムを開始
    }

    IEnumerator CoinLifetime(GameObject coin)
    {
        float lifetime = 4.0f; // コインが消えるまでの時間
        float timer = 0.0f;

        while (timer < lifetime)
        {
            timer += Time.deltaTime;
            yield return null;

            if (coin == null)
                yield break; // コインが既に消えている場合はコルーチンを終了
        }

        if (coin != null)
        {
            Destroy(coin);
            AddCoin(); // コインを獲得
        }
    }

    public void AddCoin()
    {
        coinCount++; // 獲得したコイン数を増加
        UpdateCoinCountText(); // UIを更新
    }

    void UpdateCoinCountText()
    {
        coinCountText.text = "Coins: " + coinCount.ToString(); // コイン数を表示
    }

    void DropDiamondAndRespawnEnemy()
    {
        // ダイヤを生成
        GameObject diamond = Instantiate(diamondPrefab, coinSpawnPoint.position, Quaternion.identity);

        // ダイヤに飛び出すアニメーションを適用
        float dropHeight = Random.Range(-2.0f, -4.0f); // 落下先を2倍に伸ばす
        Vector3 peakPosition = new Vector3(
            coinSpawnPoint.position.x,
            coinSpawnPoint.position.y + 1.0f, // 一度上に上がる
            coinSpawnPoint.position.z
        );
        Vector3 targetPosition = new Vector3(
            coinSpawnPoint.position.x + Random.Range(-1.0f, 1.0f), // 横の範囲を広げる
            coinSpawnPoint.position.y + dropHeight,
            coinSpawnPoint.position.z
        );

        Sequence diamondSequence = DOTween.Sequence();
        diamondSequence.Append(diamond.transform.DOMove(peakPosition, 0.15f).SetEase(Ease.OutQuad)) // 上に上がる動きを2倍速に
                       .Append(diamond.transform.DOMove(targetPosition, 0.25f).SetEase(Ease.InQuad)) // 下に落ちる動きを2倍速に
                       .OnComplete(() => StartCoroutine(CoinLifetime(diamond))); // アニメーション完了時にダイヤのライフタイムを開始

        // 敵を一瞬消して再び現れる演出を追加
        StartCoroutine(RespawnEnemy());
    }

    IEnumerator RespawnEnemy()
    {
        // 敵を一瞬消す
        spriteRenderer.DOFade(0, 0.5f);
        yield return new WaitForSeconds(0.5f);

        // 敵を再び現す
        spriteRenderer.DOFade(1, 0.5f);
        enemyLife = 10; // ライフをリセット
    }
}

追加した処理は、コインの時とほぼ同じです。

ダイヤモンドは、以下の記事で紹介したアセットを使ってます。

もちろん、今回の実装は、今後やろうとしている実装の前の前段階の下ごしらえのようなものです。

実際は敵は一瞬消えるのではなく、違う敵を出すようにしますし、ライフは変動させたいです。

ですが、そこまで作り込むのはまだまだ先にやったほうが良いと思い、今回はこのような実装にしました。

今回はここまで。

<過去の記事>

個人ゲーム開発日報|敵キャラクターの設置とDOTweenの導入
前回はCanvasのUIの設定をしました。今回は敵キャラクターを画面に設置し、タップしたら的にダメージを与えて動くモーションをつけます。敵の画像の設置まずは敵の画像を画面に設置します。敵の画像は...
個人ゲーム開発日報|コインの出現とアニメーション
今回は、敵キャラクターをタップしたらコインが飛び出るアニメーションを実装します。
個人ゲーム開発日報|コインの加算の実装
今回は、敵が落としたコインを右上の数字に加算する処理を実装したいと思います。
タイトルとURLをコピーしました