るいちゃんアバター ~Unity作業まとめ~

こんばんは。VyseArt(ヴィシェアート)のトナカイです。

 

先日東京ゲームショウ2019に行ってきましたー^^

いやーよかった!Indies Gameブースにて、実際にゲームを作っている人たちと話ができたこと、本当に良い経験になりました!

 

こういう祭典はちょくちょく顔を出した方がいいですね!

 

==

 

本日のゲーム制作進捗まとめをメモしたいと思います。

 

youtu.be

(この動画はRigidbody.AddForceで動かしています。この後にRigidbody.velocityで動かす方法に直しました。)

 

現在私たちのオリジナルキャラクター「御筆(みふで)るい」ちゃんを、小海が3Dにしてくれたので、それをスクリプトで動かしてみています。

 

ただのメモですので、技術ブログとは違い、テーマも絞らずつらつら書いていきます。

 

キャラクターを動かすのに、Rigidbody.velocityを使った

キャラクターの動かし方は、このサイトにあるように3つ4つ方法があるそうです。

 

tama-lab.net

 

この中で私が好きなのは、Rigidbodyに力を加えるものでした。

 

Rigidbody.velocityに値を設定すると、人型のキャラクターでしたら(自動車とかではなく)思ったようにスッスッと動いていってくれます。

 

ただしここで問題があって、動画のようにジャンプさせるときに、RigidBody.velocity = new Vector3( moveX , 0 , moveZ )という風に(moveXとmoveZは変数)、Y軸方向に0の値を代入してしまうと、重力が働いていたとしても、ふわーっとゆっくり落ちるようになってしまいました。

 

ここで、重力計算をしようとして、下記のサイトを参考にしたのですが、、

Unityで間違った重力の計算をしているかも!? | Unityを使った3Dゲームの作り方(かめくめ)

 

こちらのコードで奮闘したところ、解決できました。要は、重力計算をRigidvody.velocityのy軸の中に入れてあげればよく、速度の物理法則v = v0 +1/2 at^2をこのRigidvody.velocityの中に入れてあげればよかったようです。

 

Rigidbody.velocity = new Vector3( moveX, 0.5f * Physics.gravity.y * jumpTime * jumpTime , moveZ)

 

みたいな感じ。Physics.gravity.yというのはUnity側で提供されている定数なので問題なく使えます。jumpTimeというのは自分で作った変数です。

onCollisionEnterで地面(タグをGroundとかにして)との接地状況を取得して、接地時はjumpTime = 0 とします。ジャンプさせたときにjumpTime += Time.deltatimeでジャンプの時間を累積させておき、それを物理法則の式に代入すれば、落下がより実際の物理法則のようにUnityで反映させることができます。

 

(実はこの記事を書いている間に修正点に気づき、直せたので、アップしている動画はRigidbody.velocityで動いているものではなく、Rigidbody.AddForceで動いています。)

 

Rigidbody.AddForceはカーレースゲームのようなより物理的なゲームといいますか、摩擦なども含めて楽しむときに使うもので、Rigidbody.velocityは人を思うように動かしたりして、人の挙動がメインではなくて3D脱出ゲームやノベルやシュミレーション要素が主となるゲームに用いられるコードという認識を持っています。

 

というわけで、これだけのコードに1日も2日もかけてしまった私の力量って、、という感じですが、るいちゃん新しいゲームに向けて、ちょっとずつ進歩していきます。

 

つまづいたとき、とことんやるか、違う方法を探すか、どちらがいいか

ゲーム制作をして1年半くらい経ちました。5つ以上アプリを出して、その間プログラムでうまくいったりいかなかったりすることがあるのですが、そういう場合どうすればいいか指針を考えました。

 

基本の知識はとことんやる、変わり種や難しいことは違う方法を探す

今回の人型の3Dのオブジェクトを動かしてみたい、という知識はUnityでは基本です。ググるとたくさん記事が載っていますし、本にもいろんな本で動かし方が書かれています。

 

そういう知識がたくさんあふれているものこそ、ちょっとこういうことを加えたい、など独自のアプローチがあるときに、つまずいてしまうことがあるかもしれません。

 

そういう時は「なんでこれができないのか」ということに関して妥協せずに考えるということも必要です。

 

私の場合は今回は、velocityのy軸に0を毎フレーム代入していたためふわっと落ちるようになってしまった

→velocityに重力計算したものを代入すればいい

→物理法則で速度の求め方を調べる(記憶でやっていたら間違ったままだった)

→接地判定のコードを見直す(Jumpしたときに接地判定をfalseにしなきゃいけなかった)

 

など、細かくて基本的なことを落としていたため、答えに到達できない長い時間が経ちました。

 

ここで、あきらめて違う方法をとってもいいのですが、もしそうしてしまうと、「Rigidbody.velocityってなんか難しいんだよなぁ、前できなかったよなぁ」という失敗体験ができてしまいます。

なるべくそういう体験が少ない方が成功に近づけると思います。

質問をするなり、ブログに書くなりしているうちに、整理がついて答えが見つかることもあると思います(実際私がそうでした)

 

というわけで、基本的な知識と思われることは、自分で納得がいくまで突き詰めた方がいいと思います。自分の勘違いやケアレスミスの可能性が高いからです。

 

変わり種や、難しいことは別の方法を探す

私は数か月前、NCMBというモバイルバックエンドを使用することにはまっていたのですが、ビルド時に違うSDK(アドモブのもの)とNCMBのそれが競合して、死ぬような思いで解決に3日かかった経験があります。(そこそこ古くそこそこ新しいSDKを使用したら解決しました。でもそれにたどり着くのは至難でした)

 

一応その解決策もブログではいくつか載っているのですが、NCMBではなく、PlayerPrefsを使っても実際よかったですし、アドモブではなくて違う広告を使うなど別の道をとることもできます。

 

NCMB自体が一般的にすごく有名で避けて通れないUnityの知識というわけではないので、そいう言う場合は妥協して違う方法を考えることも大切だと思いました。

 

また、NCMBに画像を送信する際に、EncodeToPNGをすると送れるのですが、私は透過設定をしたEncodeToJPGで送りたくてしばらく格闘した時期がありました。結局、NCMBではEncodeToJPGができないということがわかり、格闘した時間がもったいなかった、ということもありました。

 

あとは、async/awaitなども一般的に結構難しいといわれていて、私も使いこなせていないのでコルーチンで済ませたりしています。コルーチン自体もそんなに使いこなせているわけではないのですが…頑張ります!

 

Unityを学習するにあたって、どの知識にどれだけつぎ込んで、どの知識は今はパスするか、ということも考えて作っていきたいと思います。

 

以上