【GW企画】7日間でUnity製のカジュアルゲームを作る【2日目】

※2019年5月に書いたものをnoteに移植したものです。

「GW10連休を活かしUnityでカジュアルゲームを作ってリリースする企画」の2日目

2日目の計画

モック作成(操作の調整~当たり判定の修正)
2日目にやったこと

ドラッグ操作のX軸Y軸の調整

1日目のフライパンの動きはドラッグした画面のX軸(横軸)とY軸(縦軸)が、3Dフィールド上のX軸(横軸)とY軸(縦軸)に連動していた。
実際にしたかった動きはドラッグした画面のX軸(横軸)とY軸(縦軸)が、3Dフィールド上のX軸(横軸)とZ軸(奥行き軸)に対応させたかった。
※フライパンを縦軸に振るのはドラッグを離したタイミングで実装したかったため。

▼参考にした記事

Unityのシーン上にあるオブジェクトはワールド座標上にあり、マウスカーソルはスクリーン座標にある。という事を理解することです。スクリーン座標は単純に液晶モニターのXY座標です。ワールド座標は、無限に広がるXYZ座標で、ここにゲームオブジェクトが配置されています。

スクリーン座標とワールド(フィールド)座標が別々だと意識して実装。

スマホには「カーソルを乗せる」という動きは存在せず、極論を言えば「タッチしているか・していないか」しかありません。
なので「タッチする」に相当するOnMouseDownや、「タッチしたまま動く」に相当するOnMouseDragはそのまま使えますが、マウスオーバーやポインター系は使えません。

SP対応していない実装について予め調べておいた。
実装時の確認はほとんどPCで行っていくため、後半戦のスマホチェックするタイミングで気が付かなくてよかった。

スクリーン上のX軸Y軸のマウスのドラッグ&ドロップの動作とワールド上のX軸とY軸のオブジェクトの移動を連動させるコードは上記を参考に実装した。

指を離した際にフライパンが跳ねる動作の実装

void OnMouseUp()
{
//マウスを離したときに鍋の傾きを戻す
this.transform.Rotate(-15.0f, 0.0f, 0.0f);
}

OnMouseUp()を使ってマウスを離したタイミングでフライパンの座標が変わるように変更。

当たり判定の修正(地獄編)

ここまでは割とスムーズにきたものの、ここから地獄だった。
フライパンに乗せたオブジェクトが時たますり抜けるのである…。
さらに米粒のような小さいオブジェクトだと振った瞬間にすり抜ける。
これを改善するために四苦八苦した。

▼Fixed Timestepを変更してみる

どうやらEdit>ProjectSettings>TimeにあるFixed Timestepという項目を下げることで当たり判定のチェック頻度が上がるとのことだ。
これを 0.02 → 0.005 に変更した。
確かにステーキのような大きなオブジェクトではすり抜け頻度が減った気がするものの、お米がすり抜けることには変化がなかった。

参考)

ここの数字を下げることで、衝突判定のチェック頻度を向上させ、より高精度の判定が行えるわけです。
ただし先ほども説明した通り、チェック頻度が増えればその分負荷も上がるわけなので…
頻度を上げすぎるのも考えものです。

▼Rigidbodyの設定の見直し
Rigidbodyの設定見直しでも当たり判定の精度が変わるらしい。
「Collision Detection」を設定すると「高速で動くオブジェクトが、衝突を検知せずに他のオブジェクトをすり抜けてしまうことを防ぎます。」らしい、、!

さっそく「Continuous」「Continuous Dynamic」や「Continuous Speculative」などに変えてみるものの米粒のオブジェクトでは変化無し…。

▼Mesh Colliderの設定を見直す
フライパンに使ってるMesh Colliderの設定周りが怪しいかもしれないとのことでドキュメントを確認してみる。

「オンにすると、MeshCollider は他の MeshCollider と衝突します。」というConvexをONにしてみたものの反応変わらず…。

▼Box Colliderで囲んで見る
MeshがだめなのであればBoxを使ってみればよいじゃないということで、Box Colliderで囲んでみる。
円状のフライパンを四角の形で囲んだおかげで、すり抜けが酷くなったようにも見える。
そして米粒の当たり判定についても変わり無し。
この辺りでハゲそうになってくる。

画像1

ガバガバなBOX Colliderの図

▼『当たり判定』でチェックすべき10のポイントを試してみる
世の中には素晴らしいまとめをしてくれている人たちがいる。
この初心者ホイホイの当たり判定で嵌りそうなポイントをまとめてくれる神がいた。

①『Rigidbody』がアタッチされていること
②Rigidbodyの「Simulated」にチェックが入っていること
③両方のオブジェクトに『Collider』がアタッチされていること
④両方のColliderの『Is Trigger』のチェックが外れていること
⑤Colliderのサイズが適切に設定されていること
⑥接触を検出するための関数が正しく使用されていること
⑦スクリプトが対象オブジェクトにアタッチされていること
⑧コンポーネントや関数で、2Dと3Dを混同して使用していないこと
⑨『Layer Collision Matrix』の対象項目にチェックが入っていること
⑩Rigidbodyの「Collision Detection」を「Continuous」に設定

多分たいていの項目であればこの10個に網羅されているのであろう…。
10個のチェックを試したものの米粒は落ち続けるのであった…。
(もしかしたら自分の不注意で見落としていたものがあるのかもしれないが…)

▼Assetに頼る(金で解決しよう、、!)
二進も三進もいかなくなり、ついにAssetで解決しようとする。
とりあえずColliderの当たり判定を細かくすればなんとかなるんじゃないかと思い色々とAssetを入れてみた。

Meshに合わせてColliderを生成してくれる便利なアセット。しかも無料!


Colliderに円錐形とか色々な形のバリエーションを追加してくれる便利なアセット。
普通に作ったら複雑な形も呼び出せる。

Meshをとにかく細かく設定してくれる便利なアセット。
設定した値にそって可能な限り細かく設定できる。

上記のような便利なアセットを導入したものの、結論米粒がフライパンからすり抜けるのは防げなかった…。
※自分の使い方が悪かったんだと思います…。

この辺で2日目は挫折しました…。ステーキを柔らかくするチャレンジ
当たり判定で気が狂ったので、一旦当たり判定から離れることに。

ステーキをやわらかく表現できないかと方法論を探してみる。

▼Cloth Componentを使ってみる
ちょろっと調べるとVRchatのキャラクターの服を柔らかくするのにCloth Componentが使われてるっぽかった。
それをステーキに流用してみようとしたものの、ステーキがフライパンを貫通するようになってうまくいかない。
(当たり判定を使いながらCloth Componentを使う方法が見つからなかったので断念…)

▼NVIDIA Flex for Unityというアセットを使ってみる

また無料の素晴らしいアセットを見つけてしまった。
そしてわかりやすい解説のQiitaも見つけることができた。

結論うまくやわらかくはなったものの、利用しているステーキのアセットとのサイズ感がマッチさせられることができずゲーム内での利用は断念した。
でも柔らかいオブジェクトの表現ができる素晴らしいアセットだったし、別の機会にまた使う予定。

2日目の振り返り

とにかく当たり判定と一日中向き合っていた日であまり進捗出せなかった。
こういうときこそstack overflowとかで質問すべきなのかもしれないが、変なところで引っ込み思案な癖がありググっているだけで時間が過ぎてしまった…。
企画の再検討も視野に入れたところで2日目が終了した。

この記事が気に入ったらサポートをしてみませんか?