![見出し画像](https://assets.st-note.com/production/uploads/images/36505935/rectangle_large_type_2_49af4aa1c372fc6967e95967ae4f6b85.png?width=1200)
円周率を求めるアプリ
先日、数学やハッカソンの記事を書き、制作意欲が湧いたため、土日の2日間にて一人ハッカソンなるものを行いました。
クリックゲームと数学を組み合わせて、円周率を求めるアプリを作りましたので備忘録としてまとめておきます。
期間:2日(18時間くらい)
人数:1人
言語:C#
プラットフォーム:Unity
説明
ただ画面をタッチするシンプルなクリック(タップ)ゲームと数学の知識を組み合わせたiosアプリ。「ビュフォンの針」という針を落とすことにより円周率を求める数学的方法をクリックゲームにより実現した。画面をクリックすることで針が落ちてくる。針を落として、台の上に引かれている線と接した回数により円周率を求めていく。クリックすればするほど、より正確な円周率を求めることができる。また、円周率の導出の仕組みもアプリにより学ぶことが可能である。
動画
アプリできた pic.twitter.com/zjIb1Gvr1C
— mo (@momomorgentau) October 11, 2020
ちゃんと貼れてますかね。
動画にて
l = 2d
となっていますが、正しくは
d = 2l
です。下の画像では修正をしておきました。
動機
最近、Unityを触っていなかったため、なにか形になるようなものを最後まで作りきることで、Unity、C#に再び触れ合うために作成。本アプリにした理由は、最近閲覧した「ビュフォンの針」という手法に感銘を受けて、なおかつ、クリックゲームと非常に相性がよいと考えたため。
工夫
本手法において、数学的な説明がなされているが「針の太さは理論上0である。」という点の実現に手間取った。UnityのcolliderとRigidbodyにより衝突のコールバックを検知すると、必ず針の幅による誤差が生じる。
そのため、針のオブジェクトの両端に微小な座標を取得するためのオブジェクトを設けた。オブジェクトのワールド座標を取得し、中間値の定理に従い線との接点があるかを求めた。これにより、針の幅を0を実現した。
また、衝突に物理演算を用いないため計算負荷の軽減にもつながった。
あと「クリックゲームは積み重ねて増やしてく」ことが重要だと思うので、セーブ機能も追加しておきました。
反省
実装当初、針を落とす挙動を管理する「GameManager」をシングルトンにて、それを中心としたクラス構造を予定していた。しかし、シングルトンに対して、一部シーンでしか登場しない「床のオブジェクト」をアタッチする必要がでてきたため、2度目のシーン遷移において「Null Reference」となった。上記の解決のために、「GameManager」をシングルトンではなく、staticなクラスとして扱うこととした。そのためか、セーブを管理する「PlayerSaveData」といったスクリプトをもつオブジェクトを複数用意することとなってしまった。
ゲーム全域に渡るクラスを「GameManager」のシングルトン、針を落とす部分のクラスを「PlayManager」としたほうが一貫した実装となったと思う。
あと、今回できなかった点として、
・針の挙動をコルーチンにて管理したが、値の変化をコールバックとして受け取れるUniRxなるものがあるらしい。
・構造体を他クラスのメソッドの引数に取りたかった。(どうやるんだ?)
・publicばっかなので、get setのprivateで管理したい
を次回の実装の時には達成できるように頑張ります。
感想
はじめは5時間ぐらいでできるもんだと思っていたけど、実際手を動かしてみると、エラーが頻出したり、実装方法が難しかったり、デザインについて悩んだりとあっという間に時間が溶けていきました。そんな中でも、なんとか完成まで持って行けたのはよかったのかなと。
あと、UI関連のボタン操作にてウィンドウを出したり消したり、シーン変えたりする実装が昔に比べて早くなったなと自分でも感心しました。あの頃は、UI使いたくなくて、何とか通常のオブジェクトで実現してました。それもそれで、今思えばアイデアの勝利かもしれません。
でも、一人の実装は寂しいですね。実装もそうだし、何よりアイデアが膨らまないですね。今度は研究室の子を巻き込んでなんか作ろうかしら。
時間を見つけて公開できる状態まで持ってきたいと思っています。
以下資料。
この記事が気に入ったらサポートをしてみませんか?