質問するログイン新規登録
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

124閲覧

Unity ジャンプの高さが毎度変わってしまう

TeratailKeita

総合スコア2

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2025/08/06 04:34

0

0

実現したいこと

Unity6で2D横スクロールアクションゲームを作っています
・入力の長さで高さを調整できるジャンプを作りたい

発生している問題・分からないこと

なぜかジャンプの最高高度が毎度変わります。動きをみたところおそらくですが、フレームレートが高くなるとジャンプの高さが低くなって、フレームレートが下がると、ジャンプの高さが高くなっていると思います。

該当のソースコード

//ソースコードの一部です↓ void Update() { Jump(); if(!isJumping ){ yMove = rb.linearVelocity.y; } float x = Input.GetAxisRaw("Horizontal"); rb.linearVelocity= new Vector2(x*speed,yMove); } private void Jump(){ //jumpTimer一定時間たったらisJumpingをfalseにする if(Input.GetKey(KeyCode.Z) & isJumping){ jumpTimer ++; Debug.Log(jumpTimer); if(jumpTimer >= maxJumpTimer){ isJumping = false; jumpTimer=0; } }else{ jumpTimer = 0; } //isJumpingオフ if(Input.GetKeyUp(KeyCode.Z)) { isJumping = false; } if(!isGround) return; //isJumpingオン if(Input.GetKeyDown(KeyCode.Z)) { isJumping = true; } //move if(isJumping) { yMove = jumpForce; } }

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

ネットで調べた結果、time.deltaTimeが関係していると推測しましたが、そもそもTime.deltaTimeをどこにかければいいのかわからないうえに、Time.deltaTimeがこの問題に本当に関係しているかもわかりません。もしよかったら教えて下さい。

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

jumpTimer が、経過時間ではなく、フレーム数になっているのが原因に思えます。

Update() は、フレーム毎に呼ばれますので、maxJumpTimerが120だとした場合、120フレームの間、上昇します。
実際の上昇時間は、フレームレート120で1秒、同60で2秒となりますので、フレームレートが高いほど、ジャンプの高さが低くなります。

修正としては、jumpTimer とmaxJumpTimer を、フレーム数から時間に変更、
jumpTimer ++ としている個所を、jumpTimer += Time.deltaTime としてみてください。
なお、jumpTimer が int や long などの整数型の場合、floatなどの浮動小数点型に変更してください。

投稿2025/08/06 14:46

YT0014

総合スコア1839

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TeratailKeita

2025/08/06 22:43

jumpTimer++;からjumpTimer+=Time.deltaTime;にしたら一定のジャンプを作ることができました。ありがとうございます。 m(_ _)m
guest

0

デバッグしてみないとわかりませんが、ソースコードを見る限りでは、

  • linearVelocity代入している
  • RigidBody の操作を FixedUpdate ではなく Update で行っている。

という点が気になります。(何となく RigidBody ではなく RigidBody2D のような気がしますが、同じことなのであえて区別しません)

linearVelocity (初めて知ったのだけど、軽く調べる限り従来の RigidBody.velocity と同等のもののようなので、そのつもりで話しますが)とは、全ての物理演算による 移動値です。
「全て」というのは、あなたがスクリプトで書いているジャンプによる上昇力だけでなく、重力、空気抵抗などなど、「全て」です。

ですのでそこに代入するということは、全ての物理演算の移動量をクリアした上で 移動値を設定することになります。
velocity について調べると、「リアルの動きを無視したい場合には、velocity に設定しよう」なんて書かれていることもありますが、それは他の物理演算をクリアするから、という意味合いがあります。
(ただ、これを鵜呑みにしていいかは、私は疑問ですが)

そして、FixedUpdateUpdate については、Unityの物理演算に関しては重要な話であり、そこらじゅうで語られていることですので、しっかり調べてみてください。

簡単に言えば、FixedUpdate はどんな環境でも一定間隔で処理されるもの、Update はフレームレートなどにより不定な間隔で処理されるものとなります。
そして、物理演算は FixedUpdate のサイクルで処理されますので、物理演算の処理は FixedUpdate で行え、というのが、Unityの物理演算の常識となっています。

つまり、FixedUpdateUpdate の呼ばれる回数は、場合によっては2:1だったり、3:1だったりすることになります。
そこで、先程言ったことを思い出していただきたい。Update で重力など全ての物理演算の移動量がクリアされると言いました。
それは、前者の場合、2回に1回は重力がクリアされる、言い換えると2回に1回は重力がクリアされないことになります。そして後者は同じように考えると、3回に2回はクリアされないことになりますから、前者と後者で重力のかかり具合が違ってきますね。
まぁ、例えがアレでしたけど、Update の呼ばれるタイミングが違っていて、それによって重力のかかり具合が違ってくるのでは?ということは理解していただければ幸いです。

というわけで、Unityの物理演算の常識に従って、「移動する力をうわ得る場合は RigidBody.AddForce を使う」「物理演算処理は FixedUpdate で行う」を守ったほうがよろしいかと思います。

投稿2025/08/06 13:50

katsuko

総合スコア3603

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TeratailKeita

2025/08/06 22:43

FixedUpdataとUpdataについて、存在がややこしすぎる故にあまり深く考えず、とりあえずUpdataに重力クリアのコードを突っ込んでいましたが、確かにいわれてみるとFixedUpdataに入れないと重力クリアが起きない時と起きる時にわかれてしまいますね。これは気づきませんでした。回答ありがとうございます。 m(_ _)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問