FixedUpdateとUpdateごちゃまぜでTransformをいじるとカクつく
VRの諸々もトロッコゲ―も進捗していません。
ここのところは、VRでスクリプトいじった際に、よくVectorとかQuaternionとかアニメーションとか色々必要な知識があるなと実感したので、 とりあえず3Dゲームのサンプルらしきものを見ながら勉強してます。
最近では、以下のAC4系のカメラワーク再現の記事を試してました。
カメラワーク違うだけで、だいぶスピード感というか雰囲気変わるなーと。
カメラをプレイヤーオブジェクトの子にしたり、LerpやLookAtで単に追いかけるだけだと、あそこまでスピード感はちょっと出ない気がします。
それとこの記事を読んだときの所感が、しばらく前にどこかで見た至言「ゲームを思ったように作れるようになるには、自分で考えて分析して実装することを繰り返す」ということの体現なのだなぁと、なんとなく感じました。
「AC4のカメラワークすごいけど、どうやっているのかわかんね(ᐛ) パァ」だった自分が恥ずかしいです。
とりあえず、記事ほぼそのまんまでモデルをSDユニティちゃんにして出来上がったのが以下の感じ。
一応、エフェクト入れたり、デバッグ用のオブジェクト表示してたり、ログ出してたり。 このときはGifアニメでしか録画してなくてサイズ抑えるため画質粗いですが…。
あとPlayerMove.csは記事のままではないです。CharacterController使って移動させてます。 (ついでにカメラの位置もSDユニティちゃんの前に出ないようにしています)
この記事ほぼそのままでSDユニティちゃん動かしてカメラワーク考えてた。カメラがSDユニティちゃんの前に行かないよう制限してみたけど、ちょっと頭が悪い方法だったのでやり方考えよう…
— kb(転職したい) (@job_zero) 2018年1月22日
【Unity5】AC4系のようなカメラワークを再現する - N煎ログブログ https://t.co/XGzOvyB0f3 pic.twitter.com/waxH0D6E6a
実は、これを動かすときに、PlayerMove.csを自前でやったせいで、ぶち当たった問題が動きのカクつきでした。
なんか動きがカクつく
実は動かしている過程で、動きがすごくカクつくときがありました。それが以下の動画です。
FixedUpdateとUpdateごちゃまぜでのカクつき pic.twitter.com/wzLUsg63FS
— kb(転職したい) (@job_zero) 2018年1月29日
ちなみに上の記事にあるサンプルコードを本当にそのまま適用したら、この現象は起きないです。
これが起きたのは、PlayerはUpdateで移動処理しているのに対し、それの動きに合わせて追従させているCameraRotateOriginとMainCameraをFixedUpdateで処理させていたせいです。 (上の参考記事ではプレイヤーオブジェクトの移動はFixedUpdateで行っています。)
図で表すと、以下の関係です。
最初はなんでカクついているのか、さっぱりわかりませんでした。
そのときは、Game画面ではカクついているけれど、Scene画面を見ているかぎりではSDユニティちゃんの動きがカクついているわけではなく、追従させているオブジェクトがカクついているので、最初はLerpの補間具合が粗いのかなと、 ぼやーと思ってました。
ただ、参考記事のPlayerMove.csをそのまま適用するとカクつかず、自前のPlayerMove.csにしたらカクつくので「あっ違う」となりました。
問題はFixedUpdateとUpdateのそれぞれで移動処理していたこと
この辺りは以下の記事が問題解決につながりました。
(最初はLerpについて調べて、うんうん唸っていた)
要は、FixedUpdateとUpdateの呼ばれる周期がズレているせいで、ごちゃまぜにしたら、カクつきが起きやすいようです。 こんな分かりやすい記事、書けるようになりたい。
解決する(滑らかに動いているように見せる)には、
- Rigidbody.interpolationを使うか
- Fixed TimeStepを短くしてFixedUpdateの実行周期を短くするか
というところらしいです。
(ただ、これはFixedUpdateとUpdateどちらも使わざるを得ない状況での場合っぽいです。)
どちらの選択肢も、処理コストが結構かかるので、避けられるのであれば避けた方がよさげでした。
ただ、Fixed TimeStepをかなり短くして描画ズレが起きないよう、実行周期を短くするのはレースゲームやVRゲームでは取られる手法とのことで、場合によっては今後使う場面も出てきそう。
しかしながら今回の場合は、Rigidbodyを使っていないので物理計算はほぼしておらず、そもそもFixedUpdateにする必要がなかったため、FixedUpdateではなく、Updateに統一しただけで大丈夫でした。
選択肢としても①はRigidbodyは使っていなかったので出来ないですし、②も処理コストが結構増える割に、ズレる可能性もあるなぁと…。
また、RigidbodyつけてAddForceしているときは、FixedUpdateに統一すれば大丈夫そうです。
ちなみに直った結果が以下の動画です。ついでにブログでまとめることを機に動画の撮り方とか編集調べたので、最初のGifアニメより画質UP!
FixedUpdateかUpdateのどちらかで統一 pic.twitter.com/OaGcazwUoK
— kb(転職したい) (@job_zero) 2018年1月29日
最後に、②のFixed TimeStepを短くするのを試したのが以下の動画です。結構改善してます。
(Fixed TimeStep:0.02 → 0.001)
値をかなり下げているのは、0.01にしたくらいじゃ大して改善しなかったためです。
FixedUpdateとUpdateごちゃまぜでFixed TimeStepを0.02→0.001に変更 pic.twitter.com/vm72tZLar9
— kb(転職したい) (@job_zero) 2018年1月29日
かなり改善しましたが、厳しめに目を凝らすと少しブレる瞬間があるなぁという感じです。
(追記) Fixed TimeStepを下げるなら、ディスプレイの60Hzに合わせて、1/60の倍数にすべきでした。
ただ、1/60とかにしてもやはり処理が重くなったときはブレたりしていたので、どちらかに統一するのが無難っぽいです。
UnityでMMDモデルにVRIK使ったら手首の角度が変になったので直したい
未だにUnity出来ないマンしています。
8月くらいにVRIKを試して、手首の角度がおかしかったのを放置しつづけ、アドホックなやり方ですが、修正出来たので、自分用メモとしてまとめます。
とりあえずVRIKで動かす
UnityでMMDモデルを使えるというのは、MMD4Mecanimを使えば簡単にできるということが分かってましたが、 どうやらVRコスプレする際もVRIKというFINALIKのアセットを使えば、結構簡単にできるらしいとのことで早速試した結果がこちら。
適当にやった割には意外と上手くいっているように見えるんですが、手首がおかしいです。
別におかしな方向に曲げてたのではなく、手のひらを頭側にして両手をただ上げた状態です。
「なんでこんなことになってるんだ?」と思いながらも、Unity上でモデルの手首の角度を最初から変えたとしても実行すると全く無意味だったので、 変えるならインポートする前のモデルの情報をいじらないといけないのかなーとか、 トラッキングの手首の角度をとるところを変えるのかなーとか、 ぼんやり悩みながら、気が付いたら2か月くらい放置してました。
このときに参考にしたVRIKやFINALIK、MMD4Mecanimの記事がどれだったか完全に忘れてしまいました…。
MMD4Mecanimで取り込むときは、Humanoidでしましょうとか、モデルは十字になってないと上手くいきませんとか、そういったことが書かれていた記事があった気がするんですが、思い出せない。
うろ覚えですが、他では以下の記事を参考にしたような気がします。
ちなみにOVRPlayerControllerは使っておらず、OVRCameraRigを使ってます。
手首がおかしいところを直す
インスペクターでいじれるパラメータではどうしようもなかった(少なくとも見つけられなかった)ので、
VRIKのスクリプト -> OVRCameraRigのスクリプト
の順番でスクリプトを見ていきました。
VRIKはどうやら位置トラッキングはしておらず、動かすIKのモデルのReferenceを定義したりするだけっぽかったので、 Solverで指定しているのがOVRCameraRigのAnchorだったこともあり、OVRCameraRigに手のトラッキングのスクリプトがあるのだろうと思い、 該当箇所を探して、適当にオフセット値をぶっこむことにしました。
[OVRCameraRig.cs] // 省略 // // public変数の諸々が終わったあたりにつぎ足す // Startのところで初期化 // 値はモデルによって変わると思います public float lhandoffset_x; public float lhandoffset_y; public float lhandoffset_z; public float rhandoffset_x; public float rhandoffset_y; public float rhandoffset_z; // 省略 // private void Start() { UpdateAnchors(); lhandoffset_x = -90f; lhandoffset_y = 90f; lhandoffset_z = -30f; rhandoffset_x = -90f; rhandoffset_y = -90f; rhandoffset_z = 30f; } // 省略 // private void UpdateAnchors() { // 省略 // trackerAnchor.localRotation = tracker.orientation; centerEyeAnchor.localRotation = VR.InputTracking.GetLocalRotation(VR.VRNode.CenterEye); leftEyeAnchor.localRotation = monoscopic ? centerEyeAnchor.localRotation : VR.InputTracking.GetLocalRotation(VR.VRNode.LeftEye); rightEyeAnchor.localRotation = monoscopic ? centerEyeAnchor.localRotation : VR.InputTracking.GetLocalRotation(VR.VRNode.RightEye); leftHandAnchor.localRotation = OVRInput.GetLocalControllerRotation(OVRInput.Controller.LTouch); rightHandAnchor.localRotation = OVRInput.GetLocalControllerRotation(OVRInput.Controller.RTouch); // 付け足したところ leftHandAnchor.localRotation = leftHandAnchor.localRotation * Quaternion.Euler(lhandoffset_x, lhandoffset_y, lhandoffset_z); rightHandAnchor.localRotation = rightHandAnchor.localRotation * Quaternion.Euler(rhandoffset_x, rhandoffset_y, rhandoffset_z); if (UpdatedAnchors != null) { UpdatedAnchors(this); } }
いかにも手のAnchorの回転取得してますってところがあったので、そのあとに無理やり修正したい角度を加算する感じ。
Quaternionという訳分かんないものがあるので、テラシュールブログのこの記事を参考に適当に足し込む。 後で本気でQuaternionを勉強しないといけない気がする…。
直った結果がこれ
いろいろまだ直さないといけないところを感じるけど、手首が変な角度で曲がるのは直った感じ。かわいい。
なんか手首ひねると、ツイストするみたいにちぎれそうになったり、腕とかが手首の位置優先で体突き抜けたり、いろいろ問題がありそう。
0618-0625 unity1week 参加しました
2017年6月のunity1week参加しましたので、感想です。
パンツ積み上げ回収 | ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう
0日目(Sun)
0時からお題が出たので、何を作ろうか考えてました。
とりあえず、「ステラのまほう」でやってたように、最近あった出来事からの単語やフレーズを書き出したり…。
そのときで「よし!これ!」で決まったのは…。
「石やウンコを積み上げて壁を作り、お婆ちゃんがものすごい勢いで強行突破する」
ハイスピードお婆ちゃん。
小学生のときの自分がノートの端っことかに落書きしてそうな感じ…。
最終的にはお蔵入りになったけど、なんか面白そうだからいつか作ってみたいかも。
1日目(Mon)
0日目で考えたものをどうやって作っていくか考えてました。
とりあえず、2Dドットかな…とぼんやり考えてました。
自分がドット絵を描く場合、いまだにアニメーションを作るのが時間かかってしまうので、ほぼ素材づくりで終わるかなと思ってました。
ただ、せっかく新規でゲーム作るなら、あんまりやったことないことやろうと思って、それまで考えたものを全部やめました。
じゃあ代わりに何を積んで、どうしようかと考えた際に、真っ先に思い浮かんだのが
「パンツ積みたい」
パトスが溢れて、何がなんでもパンツ積もうと思いました。
せっかく0日目で考えたものを全部なかったことにしたから、どうせなら2Dドットもやめよう!
そうだ!3Dにしよう!
その勢いのまま、ちょっと前にかじったBlenderでパンツの3Dポリゴンを組んで終わりました。
このときのテンションは今でも謎。
2日目
出来上がったパンツに色を指定して、とりあえず「ふわふわなパンツ」にするにはどうすればよいかを調べてました。
本当は落ちるときや、着地したときのパンツのアニメーションが組めればよかったのですが、
アニメーションの組み方を知らず、勉強している時間はなさそうなので、手っ取りばやく実現できる方法を探していました。
そしたら、それっぽいのがありました。
Yes!Clothコンポーネント!
旗を振る
ndabecha.blogspot.jp
これを見ながら、パンツの3Dポリゴンをインポートして、パンツを落としました。たぶんそれっぽい。
ついでにPrefab化して、増殖させました。(gifが重くてはてブロに上がらないので埋め込み)
2日目。とりあえず、パンツを落とすのを増殖させて積み上げて崩れるところまで。ゴールが見えないー。#unity1week pic.twitter.com/3WOAqSQ2Qw
— kb (@job_zero) 2017年6月20日
2日目までは意外と順調だなーくらいに思ってました。
3日目
パンツを増殖させながら、やっぱり少し重いなーと思っていたら、テストプレイしながらUnityが急に落ちることが増えました。
やっぱり重いのか、と思ったけれども、落ちるのはパンツを100個くらい増殖させた場合だったので、20~30個くらいの制限にすれば大丈夫かなと、ゆるーく考えてました。
とりあえず、パンツだけじゃ味気ないから、前から気になっていたSDユニティちゃんを使おうと思って、インポートした後どうするのか調べてました。
SD版ユニティちゃんでユニティちゃんのモーションを使う|ゆにてぃメイト
3日目は、SDユニティちゃんのアニメーションとかの使い方を見ながら、終わりました。
4日目
帰宅後、まさかの寝落ち…。
進捗ダメです。
5日目
ここからかなり迷走してました。「ステージどうすればいいだろう?」
- 横のみの移動にしてSDユニティちゃんを移動させて、頭の上にパンツを重ねていく、…とか。(↓のgifは後から作った再現)
- 色々無料のアセットをいれて、部屋のタンスからパンツが噴き出して、それを回収する、…とか。
俯瞰からの部屋は、SDユニティちゃんの顔が見えないので止めました。やっぱり美少女の顔が見たい。
横移動のみは、なんとなく「パンツを積んでたらSDユニティちゃんが妨害してくる」というのにしたくて、横移動だけだとすぐに詰みそうなのでやめました。
結果、壁とかなくして、低めな俯瞰で見て、空中に浮かぶ平面上、落ちたら終わりとしました。(最終的にできたゲーム)
このときまでのSDユニティちゃんは、パンツ回収キャラに衝突したら、SDユニティちゃんが向いている向きにAddForceしてくる予定でした。
やめた理由は、意外と邪魔すぎて、パンツが1、2枚くらいしか積めなかったせいです。
6-7日目は連日出勤だったので、ここで追い込みたく、パンツの積み上げまで頑張りました。
ただ問題が…。
パンツ固定問題
パンツを積み上げていく上で最初考えたのが、「籠を作って、その凹の中に入れていく」
でもコライダーを突き抜けてしまう現象ががが…。
ちょっとどうすればいいのか分からなくて、先人たちの知恵はないものかと探しました。
最初は摩擦係数上げまくって、着地したら全く動かんぞってくらいで行けるか試しましたが、ダメでした。
突き抜けてしまうんじゃあ仕方ない、とりあえず固定!と思い、今度はJointを使ったものを試しました。
その結果が下の挙動不審なバグへ…。
色々調べたりしていたら、これが正解?というのを見つけました。
コライダーは突き抜けなくなりましたが、パンツを積み上げて籠からこぼれるのが何とも悲しくて、結局は固定の道を探りました。
Jointはダメなので、どうすればいいんだろうと思ったら、ふと
そもそもSDキャラに籠固定してるじゃん
と気づき、パンツも子オブジェクト化すれば固定されるのでは、と思い至り、実際にやったら固定されました。
ここで5日目は終了(6日目には突入している時間で)。
6日目
朝から夜までお仕事で、最終日も仕事なので、ゲームとしての内容はここまでで終わりにするしかないと割り切りました。
とりあえず、ゲームオーバーになったらロードしなおせるようにしました。
後は、タイトル画面を作ろうとしたのですが…。これは上手く作れなくて、途中でやめました。(↓作りかけの画面)
後は、効果音やBGMを入れたり。
このとき、Music is VFRさんの効果音はまさに思い描いていた効果音だったので、テンション上がりました!w
後は細かい値の調整や、スクリプトでおかしいところの修正とかしてました。
7日目
WebGLへの出力を調べてました。
単に、Build SettingsからSwitch Platformするだけか、なんだ簡単じゃん( ^ω^)
と思っていたら、Switch Platformしたら、一面真っ白になってビビりました。
- Before → After
原因は、PostProcessingを使ってLightingの設定をしていた際に、Player SettingsのColor SpaceをLinearにしてたら、WebGLだとLinearは駄目って怒られていたのが主な原因…。
Gammaにしたら直りました。
こういうことあると思うと、最後にはある程度時間残しておきたいですね…。
そして、出勤までに何とかアップロードしておこうと思って、アップロード出来て、テストプレイしたら、
えっやたら重い…
Unity上だとそんなに重くなかったのに、WebGLで出力したものだと、ヤバいくらいに重い。
特にパンツが増えるとき。
Clothが重いのだろうと思い、軽くする方法を探っていたら、今更見つけても遅いものを見つけてしまう。
Cloth自体が重いから、そもそもあんまり使うなってことらしい…。
とりあえずRigidBodyも併用していたので、少しでも軽くするために、急いでRigidBodyをなくし、パンツはlocalPositionを動かすことで、ほとんど気のせいくらいのレベルで軽くなった気がします。
ここまでやってタイムアップ(出勤時間)になったので、アップロードして終わりました。
終わってみて
楽しい1週間でした。ちょっと寝不足で大変でしたが…。
正直、自分のゲーム拙いなーとは思うところが多々あるものの、一通りできたのはちょっと満足です。もっとパンツに埋もれたい…。
ついでに色々勉強になった…というよりも、これをするにはどうすればいいんだ?っていうのを調べて勉強した気がします。
締め切りがあるせいで時間がないので、「後で時間があるときに調べよう」みたいなことがなくて、強制的に勉強できる感じです。
あと、バグやよくわからない現象が起きた時、ついでに時間がないと、「ああもう駄目だ」ってなって、ついググるのを失念しがちになってしまいましたが、ググるとおおよその答えは見つかりました。
たぶん、そこまで難しいことがまだ出来ない分、答えが転がっているんだろうなあとは思います。
何か躓いたときに、ちゃんとすぐググれる癖をつけたいなあと思った次第でした。
今後は、とりあえずパンツを何とか軽くする方法はないか調べたり、考えたりすると思います…。
次回もほかのひとのハードルを下げる役として参加したいです。
長文でしたが、読んでいただいた方はありがとうございました。
追記
終わってみて、そういえばPrefab含めたオブジェクトやスクリプトの管理が終盤にかけて、ひどいことになってました。
そのあたり、ちゃんとした設計方法とかあれば勉強したいなーと思います。
地味に作り続けているたまちゃんトロッコゲー
かなりゆっくりですが、作り続けてます
間空きすぎて、ソースとかどういう仕様にしてたのか忘れるくらいですが
仮組みから、おおよその素材を作って、だんだん形になってきた気がするので、
プレイのGIFアニメ置いて、頑張ってるアピールします
(FPS高めにしたせいで、重くなってしまった…)
作り続けてると、どこまで作ったら完成かっていうのが見えてこないですね。
作りながら、「あ、ここ直したい」とかが色々出てきて。
一通り出来たら完成で、あとの凝った修正は、アップデートとかなのかな。
髪を揺らしたかった
歩きアニメ作りました。
なんか不自然…。
髪を揺らそうと思って揺らしたら、髪がばっさばさに跳ね回っている。いきいきしてる。
後はトロッコと線路と背景を作れば、とりあえずの素材はそろう気がする。
またノソノソと作ります。
3日坊主
放置っぷりがすごい。
ゲーム作り、完全にストップしてました。
アニメーション作ってたら、かなり大変だったというのもあったりするのだけど。 歩きモーション、歩いてるっぽく作ったりするの難しい。 (ついでに、待機やジャンプで髪の毛とか揺れてないことに気づいた。)
それと、絵が全然下手だなってことで、何を思ったのか、絵の練習してました。 今更そこ頑張るのかよって思うのですが、やってみると楽しかったり。
模写練に飽きた後、30秒ドローイングをとりあえず継続したり。 ちゃんとオリジナルでポーズとれるように、人物画の本買ってきて読んだり。
まあ主に、仕事で休日つぶれるので、まとまった時間取りにくかったり、 仕事で疲弊してぼーっとけものフレンズ見るだけで、半日終わったりとかしたせいです。
でもこのままで人生終わりそうなので、また細々と続けられるようにしたいです。