すだちキャンパス

すだちキャンパス

やってみたこと、学んだことなどのメモ。

unity1weekに参加しました(3回目)

こんにちは。今回はきちんと1週間使って参加してみようと思い、製作中から記事を書いてみることにしました。頑張るぞー。
と書いていたものの、最終的に約2日遅刻してしまいました・・・。お盆だったので用事が入ってしまったりして忙しかったけどそれは分かっていたことなので、、スケジュール管理難しいですね。

作ったもの

f:id:sweetgohan:20200820212255g:plain
unityroom.com
こちらです。今回は先に作りたいイメージ(花火大会)があってお題に合わせる形にしてみたのですが・・・お題から作り始めたほうが良かったかもしれません。ゲーム性的には割と最悪になりました(反省)。花火の感じとか写真を撮ってシェアできる感じとかはいい感じに出来たかなと思ったのですが・・・今のところツイートして下さった方は見ていないですね・・・。

制作過程

制作過程とともに、作っていく上で初めて知った事項なども書いていきます。

移動制限にはclamp関数

今まで、移動制限などはif文でゴリ押していたのですが、Mathf.Clamp関数を使うと良いみたいです。例えば、

playerPos = this.transform.position;
playerPos.x = Mathf.Clamp(this.transform.x, minPosX, maxPosX);

のように書くとx軸方向への移動制限ができます。
【Unity】オブジェクトの移動範囲を制限するMathf.Clampの使い方

(一定時間)動きを止めたい時

動きを制御しているスクリプトを取得して、それをオフにしたら良いようです。
例えば、あるスクリプトから"moveScript"をオフにしたい場合、

 public GameObject player;
    private moveScript movescript;

    void Start()
    {
        movescript = player.GetComponent<moveScript>();
        movescript.enabled = false;
    }

のように書きます。
(Unity)Trapに触れると一時的に動けないようにする。 | monopro キッズ・プログラミング道場

カメラの実装

まず、シャッターを切るときの演出はこちらを参考にしました。
また、カメラのズームイン・アウトはこちらを参考にして作りました。
私は↑↓で操作したかったのでこのような感じで書きました。

            if (Input.GetKey(KeyCode.UpArrow))
            {
                view = cam.fieldOfView - speed;
                cam.fieldOfView = Mathf.Clamp(view, 0.1f, 60f);
            }
            if (Input.GetKey(KeyCode.DownArrow))
            {
                view = cam.fieldOfView + speed;
                cam.fieldOfView = Mathf.Clamp(view, 0.1f, 60f);

最後に、スクリーンショットの保存と使用について。こちらこちらなどを参考にして、次のように書きました。

if (Input.GetKey(KeyCode.Space) && !isTaken)
        {
            StartCoroutine(takeScreenShot());
            resultRawImage.GetComponent<RawImage>().texture = ScreenShotTexture;

            isTaken = true;
            finderPanel.SetActive(false);
            shutterAudio.Play();            
        }

private IEnumerator takeScreenShot()
    {
        yield return new WaitForEndOfFrame();

        currentScreenShotTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
        currentScreenShotTexture.Apply();
    }

実はここで、スクリーンショットを撮っても真っ白になってしまうという問題が発生していました。1日溶かした結果、最初に書いたシャッターを切る演出の際に一瞬画面を真っ白にしているせいだと判明。そりゃそうでした・・・。
結局あきらめてフラッシュぽい演出は辞めました。まあ撮影対象が花火だからいいかなと・・・。レイヤーなどを設定して上手く消す方法もあるみたいなのですが断念。
それから、最初はScreenCapture.CaptureScreenshot("ss.png");を使用していたのですが、pngで保存するとWebGLビルドだから後々エラーが出るのでは・・・?と思いこのような形にしています。

花火を時間差で連発

これも地味に苦労しました。
for文の中で時間差を作ろうとしても上手く行かなかったので、結局タイマーを回してif文で上手く処理するようにしました。

        timer -= Time.deltaTime;
        randNum = Random.value;

        if(randNum < 0.3f)
        {
            particle = particle1;
        } else if(randNum < 0.6f)
        {
            particle = particle2;
        }
        else
        {
            particle = particle3;
        }

        if (timer < 0f && fireflowerNum > 0f)
        {
            //instantiate and play
            var fireflower = Instantiate(particle, new Vector3(1, 0, 0), Quaternion.identity);
            fireflower.transform.parent = fireflowers.transform;
            fireflower.transform.position = new Vector3(Random.Range(xMin, xMax), Random.Range(yMin, yMax), Random.Range(zMin, zMax));
            fireflower.GetComponent<ParticleSystem>().Play();

            fireflowerNum--;
            timer = Random.Range(0.3f, 3f);
        }

花火を数種類かつランダムな時間差で打ち上げたかったのでこのような形にしています。

データを保存したい

称号機能的なものを作りたかったので・・・playerprefsを使ったらかなり簡単にできるんですね。
https://freesworder.net/unity-playerprefs/

衝突判定(ハマった)

NavMesh を使っていてOnTriggerEnter()で衝突判定したい時に一瞬ハマったのでメモ。
Cube: ColliderのみでIs Triggerにチェック
Unityちゃん(NavMeshついてる): ColliderとRigidBodyをつけてIs Kineticにチェック
これで反応するようになりました。

画像つきツイート

【Unity1Week】 WebGLで画像つきツイートをしたい! - NOOB UNITY
こちらを参考に実装したら簡単にできました。感謝。

反省と感想

今回は、セーブ機能・ツイート機能の搭載ができたことで勉強にはなりました。また、概ねイメージ通りのものが作れたのでその点は満足です。ただ、やはりお題に上手く絡められなかったこととゲーム性の低さが反省点です・・・。
次回はサムネ(アイコン)から考えてみるのもアリかもしれません。やはりアイコンを見てプレイするか判断している気がするので。
それからゲーム性という点では、やはりまずは身近なゲームを参考にするというのが一番良いのかもなと思いました。ただ普段そんなにゲームをしないので、次回までにもう少しリサーチしてみたいと思います。
また、同じ「花火」という題材ですごいゲームを作っていらっしゃる方もいたので、やっぱりゲーム作りもう少しがんばりたいです・・・。