HEDONISTIC PIXEL ART(跡地)

ドット絵・ゲーム開発やってる背教の士です

初めてのUnityroom投稿

明日は出勤ですがそこから連休突入。

寒さに備え、きっちり引きこもっていきたいと思います。おかか容疑者です。

 

 

 

unityroom.com

 

 

連日Unityと触れ合っていた甲斐あって、ごくごく簡素なものではございますがシューティングゲーム「Pagan Genesis(ペイガン・ジェネシス)」が完成したので、今朝Unityroomに投げてみました。

グリマル以来となるうちのこ登場のゲーム!!(後ろ姿だけ)

 

 

 

 

プログラミングに関してはProgateなどで基礎の基礎だけ学んだ程度(しかもC#でなくてJavaとか…(;´∀`))、つい最近まではUnityとは何なのかすら知らなかった人間でも自主学習とGoogleがあればここまではすぐにできるようになるよ、ってのを自分で体感できたのがまず良かったことですね。

 

既存のジャンルが存在するゲーム(アクションでもシューティングでもアドベンチャーでも)であれば、おそらくはそのサンプルとなるゲームの作り方はどこかで紹介してくださっているのではないかと思うので、それを下地にして必要な部分を随時改造していけばしっかりしたゲームは作っていけるのではないかと。

そう考えれば自分でイチから全部やらなきゃいけないワケではないので手を付けやすいんではないかなと思います。

 

 

とはいえ自分で思い描いた仕様を実装するにはググりながらどんな感じでスクリプト書けばいいのかなーってのは考える必要はあるので、いかにして実装させるか考えるのは悩みつつも結構楽しかったです(о´∀`о)

 

誰かの役に立つかもわからないし、超初心者の私がハマって悩んだ部分をいくつか自分用メモも兼ねて書き残しておきましょうか。

 

 

●プレイヤーが画面端で止まらない

 

プレイヤーが矢印キーを押し続けている限り動き続ける設定なため、そのままだと当然ながら画面端だろうと気にせず画面外へ出ていくことになります。

これはいけない(当職並の感想)。

 

最初は空のオブジェクトにボックスコライダーをアタッチしてプレイヤーのコライダーと接触させる方法をやってみたんですが、プレイヤーのコライダーをkinematicにするとすり抜けてしまう。

Dynamicにすると接触して止まりはするもののプルプル震える動作になって違和感が凄かったので、やっぱりスクリプトで制御すべきやなぁと。

 

 

kushun-games.blog.jp

 

 

こちらのサイト様で画面端の座標を取得する方法を理解したので、これを生かして画面端に来たらキー入力できませんよという仕様にしてみました。

 

void Update()
    {
        Vector2 screen_LeftBottom = Camera.main.ScreenToWorldPoint(Vector3.zero);

        Vector2 screen_RightTop = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 0));

        Transform myTransform = this.transform;

        Vector3 pos = myTransform.position;

        if (Input.GetKey(KeyCode.LeftArrow) && pos.x > screen_LeftBottom.x)
            {
            transform.Translate(-0.05f, 0, 0);
            }

        if(Input.GetKey(KeyCode.RightArrow) && pos.x < screen_RightTop.x)
            {
            transform.Translate(0.05f, 0, 0);
        }

        if (Input.GetKey(KeyCode.UpArrow) && pos.y < screen_RightTop.y)
        {
            transform.Translate(0, 0.05f, 0);
        }

        if (Input.GetKey(KeyCode.DownArrow) && pos.y > screen_LeftBottom.y)
        {
            transform.Translate(0, -0.05f, 0);
        }
}

 

 (はてブってシンタックスハイライト表示できたんですね…)

 

キーを「対応するキーを押している間」かつ「プレイヤー座標が画面端まで到達していない状態」のみ移動を実行するように指定しました。

 

 

 

●敵が破壊された時の音が鳴らない

 

AudioSourceでちゃんと音を設定して鳴らすようにしたのになぜか敵の破壊音が鳴らない(/_;)

 なぜなのか調べてみたら、どうやら「Destroyで敵を消すようにしていると、音が鳴る前にオブジェクトが消えてしまって一緒に音も消えてしまう」のだそうで……。

 

解決策としては何パターンかあるようですが、今回は「音を鳴らす専用のスクリプトを作り、それを呼び出して音を出す」方法にしました。

 

public class SoundPlayer : MonoBehaviour
{
    public void SoundPlay()
    {
        GetComponent<AudioSource>().Play();
    }
}

 ↑音を出す専用のSoundPlayerスクリプト

 

 

void OnTriggerEnter2D(Collider2D other)
    {
        if (other.gameObject.tag == "Enemy")
        {
            GameObject.Find("SoundPlayer").GetComponent<SoundPlayer>().SoundPlay();

            Destroy(other.gameObject);
            Destroy(gameObject);
        }
    }

 ↑自機の弾に設定した、SoundPlay呼び出しの記述。

Enemyタグのついたオブジェクトに当たると音が鳴って弾と敵が消えます。

 

 

●目標を達成したら画面内の敵を消し、クリア画面に移る

 

tech.pjin.jp

 

こちらのサイト様の方法をインスパイアであります。

 

 if (scorecheck <= 0)
        {
            GameObject[] enemys = GameObject.FindGameObjectsWithTag("Enemy");
            foreach (GameObject ene in enemys)
            {
                Destroy(ene);
            }

            Invoke("GoToClear", 3.0f);


        }

 

 Enemyタグのついたオブジェクトを全てeneという変数に詰め込んだ後にeneを消す。

最初はGeneretorの方(敵を生み出しているオブジェクト)も停止させなきゃいけないのかな、と思ってたんですがこれだけで問題なく処理できました( ´∀`)

その状態で3秒後にシーンが移動します。

 

 

 

他にも紆余曲折ありつつ(コンパイルできねえ!と思ったらタイポしてるのが多いこと多いこと……)、調べていきさえすれば先人の情報は豊富に溢れているため何とか乗り越えていくことができました。

どうしてもわからない問題はteratailで質問すれば何かしらの回答は得られるのではないか?というのもありますしね。

 

 

 今回の作品はあくまで試作品なので、ここを出発点・起源として真に遊んでいて楽しいゲームを作れるようになりたいですね。

ゲーム製作は面白いぞ!!