初心者用 Unity ぶつかったらアイテムが出てくる!アイテム生成処理をつくってみよう

前回は、にわとりが歩くアニメーションを作成しました。

前回の記事⤵️

ぶつかったらアイテムが出てくる!?

Left Caption
今回はにわとりからたまごが出るではなくて、何かにぶつかったら特定の場所から出てくるシステムを作ってみます

アイテムを生成するってどういうこと?

Right Caption
「生成(せいせい)」っていうのは、新しいものをゲームの中で出すこと。 ここでは、キャラクターをクリックしたときに「たまご」のオブジェクトを画面に出すことを指してるんだ。 「クリックしたらたまごが1つ出る」だけでも楽しいけど、より面白くするために、 → 大きさをランダムにしたり、色を変えたり、動きを付けたり、ちょっと変化をつけるといいよ。

たまご(Egg)オブジェクトの作成

Assets/Images/ から たまごの画像 Eggをシーンに直接ドラッグアンドドロップします。
Eggオブジェクトが作成されますので、インスペクターで、Sprite Renderer の Order in Layer を 9(この数字が大きいほど手前に表示される)にしておきます。

プレハブ化する前に「コンポーネントを追加」から2つのコライダーを付けておきます。

  • Rigidbody 2D
  • Circle Collider 2D

ヒエラルキーの「Egg」を「Prefabsフォルダー」にドラッグアンドドロップしてprefab化しておきましょう。

たまごはダクトの後ろに隠れてますが、コライダーの調整をして「レイヤー」を変更して見えないようにします。

たまごを出したい位置に「空のオブジェクト」に「EggSpawnPoint」と変更して配置します。

卵の出現位置を別指定する

Left Caption
たまごが出てくる位置はダクトポイントとは別がいいんだけど出来る?
Right Caption
「ダクトの位置」は“にわとりが到着する場所”で、 「卵が出てくる位置」は“卵が落ちる出口(穴)”のような別の場所にしたい、ということだね。

🐔 スクリプト名:ChickenMove.cs

using UnityEngine;

/// <summary>
/// 鶏(にわとり)が「餌箱」と「ダクト」を往復し、
/// ダクトに着いたときに別の位置から卵を落とすスクリプト。
/// </summary>
public class ChickenMove : MonoBehaviour
{
    [Header("移動設定")]
    [Tooltip("にわとりの移動速度(1〜5くらいが目安)")]
    public float speed = 2f;

    [Header("目的地の設定")]
    [Tooltip("餌箱の位置(Transform)")]
    public Transform feedBoxPoint;
    [Tooltip("ダクト(にわとりが到着する場所)")]
    public Transform ductPoint;

    [Header("アニメーション設定")]
    [Tooltip("歩行用スプライト(順番に8枚などを入れる)")]
    public Sprite[] walkSprites;
    [Tooltip("アニメの切り替え速度(0.1〜0.2が自然)")]
    public float frameRate = 0.15f;

    [Header("卵の設定")]
    [Tooltip("落とす卵のPrefab")]
    public GameObject eggPrefab;
    [Tooltip("卵を出現させる位置(例:ダクトの下の出口)")]
    public Transform eggSpawnPoint;

    private SpriteRenderer spriteRenderer;
    private Transform targetPoint;
    private int currentFrame = 0;
    private float timer = 0f;
    private bool hasDroppedEgg = false; // 1往復で1回だけ卵を落とす

    private void Start()
    {
        targetPoint = feedBoxPoint;
        spriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void Update()
    {
        if (targetPoint == null) return;

        // ターゲットへ移動
        transform.position = Vector2.MoveTowards(
            transform.position,
            targetPoint.position,
            speed * Time.deltaTime
        );

        // 左右反転
        if (spriteRenderer != null)
            spriteRenderer.flipX = (targetPoint.position.x < transform.position.x);

        // 歩行アニメ更新
        UpdateWalkAnimation();

        // 到着チェック
        if (Vector2.Distance(transform.position, targetPoint.position) < 0.05f)
        {
            if (targetPoint == feedBoxPoint)
            {
                targetPoint = ductPoint;
                hasDroppedEgg = false;
            }
            else
            {
                // ダクト到着 → 卵を落とす
                if (!hasDroppedEgg)
                {
                    DropEgg();
                    hasDroppedEgg = true;
                }

                // 次は餌箱へ戻る
                targetPoint = feedBoxPoint;
            }
        }
    }

    private void UpdateWalkAnimation()
    {
        if (walkSprites == null || walkSprites.Length == 0) return;

        timer += Time.deltaTime;
        if (timer >= frameRate)
        {
            timer = 0f;
            currentFrame = (currentFrame + 1) % walkSprites.Length;
            spriteRenderer.sprite = walkSprites[currentFrame];
        }
    }

    /// <summary>
    /// 卵を落とす処理(出現位置は別オブジェクト指定)
    /// </summary>
    private void DropEgg()
    {
        if (eggPrefab == null)
        {
            Debug.LogWarning("🥚 卵プレハブが設定されていません!");
            return;
        }

        Vector3 spawnPos = transform.position + Vector3.down * 0.5f;

        // 別位置を指定している場合はその場所を使う
        if (eggSpawnPoint != null)
            spawnPos = eggSpawnPoint.position;

        Instantiate(eggPrefab, spawnPos, Quaternion.identity);
        Debug.Log($"🥚 卵を落としました!(位置: {spawnPos})");
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.yellow;
        if (feedBoxPoint != null)
            Gizmos.DrawSphere(feedBoxPoint.position, 0.1f);
        if (ductPoint != null)
            Gizmos.DrawSphere(ductPoint.position, 0.1f);

        Gizmos.color = Color.cyan;
        if (eggSpawnPoint != null)
        {
            Gizmos.DrawSphere(eggSpawnPoint.position, 0.1f);
            Gizmos.DrawLine(ductPoint.position, eggSpawnPoint.position);
        }
    }
}

スプリクトを保存してUnityに戻ってきて再生すると?!

Left Caption
にわとりの向きが逆になってしまいましたね。「にわとりのアニメーションの向きが逆を向いてるので書き直して」とお願いしました
Right Caption
了解です 👍 にわとりの向きが逆になっているということは、 現在の spriteRenderer.flipX = (targetPoint.position.x < transform.position.x); の判定が左右反転している状態ですね。 つまり、「右に移動するときに反転してしまっている」ので、 この判定を逆にすればOKです。

// 🔄 左右反転(向きが逆だったので条件を反転)
        // 以前は「target.x < self.x」だった → 右向きが逆になるため反対にした
        if (spriteRenderer != null)
            spriteRenderer.flipX = (targetPoint.position.x > transform.position.x);
Left Caption
「>」の向きを変更したのね
Left Caption
直りましたね!

🧩 Unityでの設定方法

🐔 にわとり(Chicken)

  1. このスクリプトをアタッチ
  2. 以下を設定:
    • Feed Box Point → 餌箱の位置
    • Duct Point → にわとりが到着する場所
    • Egg Spawn Point → 卵が出てくる場所(別オブジェクト)
    • Egg Prefab → 卵のプレハブ
    • Walk Sprites → 歩行スプライト6枚
Left Caption
こちらの記事に書いてあります。

🥚 Egg Spawn Point の作り方

  1. Hierarchyで空のオブジェクトを作る(例:EggSpawnPoint
  2. 「ダクト」の近く、卵を出したい位置に移動させる(たとえば下の方)
  3. ChickenMoveEgg Spawn Point にこのオブジェクトをドラッグ

※この位置から卵が落ちます!

✅ これでできること

  • にわとりは「餌箱 ↔ ダクト」を往復
  • ダクトに着くと、EggSpawnPointの位置から卵がポトン
  • 卵の出現位置を自由に調整できる

まとめ

クリックをしなくてもスプリクトで行動を作れるのは面白いですね。
プログラミングが出来なくても今の時代「chatGPT」をうまく使えば簡単なゲームが作れちゃう。
ただ、「chatGPT」に質問をする方法がちょっと難しいかなって思います。
作りたいシステムをどう伝えればいいか、何度も言葉を変えてコードを書いてもらってそれを
実行するを繰り返す。いつか作れると思います。

Left Caption
次回は、購入処理を作るらしい、これも楽しみだなぁ🐓🐤

game_lob - にほんブログ村