くるしゅ~進捗4

開発

くるしゅ~の進捗です。

前回の進捗から以下を実装
・ロゴを追加
・ボタンによる操作処理を追加
・ボタンアイコンを変更
・敵を倒した際にアイテムをドロップ
・サイズの微調整

最新版はこちらで公開中。(随時変更される可能性があります。)

ロゴを追加

仮ロゴですが、起動時に表示されるようにしました。
ロゴは「Project Settings」の「プレイヤー」にて設定ができます。

ちなみに、ロゴはスプレッドシートで作成してみました。

操作ボタン

操作ボタンについてはUIの「ボタン」で追加したオブジェクトにEvent Triggerを追加し、
ポインターが押下された場合(Down)と離された場合(Up)に処理を呼ぶようにしています。
クリックをトリガーにしてしまうと、クリックしたタイミングでしか処理が呼べず、
左右移動の加速処理が上手くうごかなくなります。

コードは単純に押下された場合にフラグをOnにして、離れた場合にフラグをOffにしています。
その後は、キーボード処理と同じ個所でそのフラグを見るようにしています。

・フラグの更新処理

・キーボードの入力処理にフラグを追加


操作用のボタンのアイコンを自作してみましたが、いかんせんデザインセンスがなくてダサい。
もっとカッコイイデザインに直したい。
ロゴのようにスプレッドシートで作った方が綺麗にできるかな。

アイテムドロップ

固定砲台で連打していると基本死なないので、敵を倒したらポイントがアップするアイテムを
ドロップするようにしました。

紆余曲折がありながら、なんとかそれっぽく動くようにはなりました。
以下、紆余曲折内容

アイテムオブジェクトが生成されない

敵に弾が当たった際に、敵の当たり判定処理でアイテムのインスタンスを生成してみたのですが
どこにも表示されていない。
オブジェクト自体が生成されていない状態なので、なんでだろうと頭を捻りました。
ログを仕込んだりして調査してみると、一度生成された後に直ぐに削除されてました。

原因はアイテムのオブジェクトが敵オブジェクトの子になっており、
親である敵オブジェクトが削除されると共に子のアイテムオブジェクトも削除されていたようです。

なので、アイテムオブジェクトの親を変更。
とりあえずは、敵オブジェクトの親に設定してみると、無事にアイテムが表示されるようになりました。

GameObject pointBallIns = Instantiate(pointBall, transform.position, Quaternion.identity, transform);
pointBallIns.transform.parent = transform.parent;

アイテムの当たり判定

アイテムの生成はできましたが、当たり判定がないので床を素通りしてしまいます。
当たり判定を付けて、床に落ちるように変更。
しかし、敵にぶつかって転がったり、自機がアイテムの上に乗ってしまったりと
あまりよろしくない挙動に。
自機に触れた瞬間にアイテムを削除しても一瞬、乗ってしまいます。

各オブジェクトがどのオブジェクトと当たり判定を持つかは「Project Settings」の「2D物理」
にある「レイヤーの衝突表」で設定することができます。
それぞれ、同じ挙動のオブジェクトをレイヤー単位で管理する必要があります。

これで、アイテムと床、壁のみ当たり判定が設定できる!
と思ったのですが、自機とアイテムが衝突しても「OnCollisionEnter2D」のイベントが発火せず
アイテム取得処理が動かない。
まぁ、衝突判定なしにしたのでそうなりますよね。(物理的演算処理のみ無効にしたかった…。)

ということで、今度はオブジェクトの当たり判定をトリガーに変更。
トリガーにすることで、物理的にぶつかったりすることなく、「OnTriggerEnter2D」
イベントで衝突を検知することができます!

・・・が、トリガーにすると今度は床との当たり判定もなくなり、床をすり抜けてしまう状態に。
最初の状態に戻ってしまった。

色々と調べてみましたが、これといった解決方法がみつからないかったため、
床と接触した際に、コード上で移動量を0、重力などの物理演算の影響を無効化にして止めることに。
また、移動速度が速いと床にめり込んでしまうため、床の位置までアイテムの位置を移動。

        if (col.gameObject.tag == "Ground")
        {
            Rigidbody2D rb = gameObject.GetComponent<Rigidbody2D>();
        // 移動量を0にして停止
            rb.velocity = Vector2.zero;
        // 物理演算の影響を無効化
            rb.isKinematic = true;
     // 床の位置にアイテムの位置を合わせる。
            Vector2 pos = transform.position;
            GameObject groundObject = GameObject.Find("Ground");
            float groundHeight = groundObject.GetComponent<SpriteRenderer>().bounds.size.y;
            float pointHeight = gameObject.GetComponent<SpriteRenderer>().bounds.size.y;
            pos.y = groundObject.transform.position.y + groundHeight / 2 + pointHeight / 2;
            transform.position = pos;
        }

泥臭いですが、昔はこうやってコーディングしてゲームを作っていたことを思い出し、
懐かしい気持ちになりました。

アイテムの種類やら

ドロップするアイテムは乱数によって変更。
80%で1ポイントの通常ポイントボールが3つ出現。
10%で5ポイントのビックポイントボールが1つ出現。
10%で回復アイテムが1つ出現。

アイテムは10秒で消滅。5秒前で点滅、3秒前で点滅が早くなる。
こちらも泥臭い実装。マジックナンバーだし。
条件ももっときれいに書くべきか。直しておこう。

   public void lifeCycle()
    {
        timeElapsed += Time.deltaTime;
        float level = 1f;
        if (lifeTime - timeElapsed  >=  5)
        {
            level = 1f;
        }
        else if (lifeTime - timeElapsed >= 3)
        {
            level = Mathf.Abs(Mathf.Sin(Time.time * 10));
        }
        else if (lifeTime - timeElapsed >= 0) 
        {
            level = Mathf.Abs(Mathf.Sin(Time.time * 30));
        } else
        {
            Destroy(gameObject);
        }

        SpriteRenderer sp;
        sp = GetComponent<SpriteRenderer>();
        sp.color = new Color(1f, 1f, 1f, level);

    }

円形の当たり判定による問題

一通り実装できたので、姪っ子に遊ばせてみることに。
すると、端っこに落ちたアイテムが拾えないとのこと。
自機の当たり判定が円形のため、壁と自機との間に隙間ができて取得できなかったようだ。
こちらはアイテムの当たり判定を広げて対処。
実際に動かしてみないと、こういう問題には気づけないですね。

コメント

タイトルとURLをコピーしました