· 

【Unity】AddForceに関する覚え書き

Last Updated  2024.02.09


Unity ダウン回避サンプル

 ダウン回避を実装した際に混乱したので、自分の為にまとめておきます。

基本構文

using UnityEngine;
 
public class Sample : MonoBehaviour//基本構文サンプル
{ private Rigidbody rb; void Start()
{ rb = GetComponent<Rigidbody>();//リジッドボディを習得 } void FixedUpdate()
{ rb.AddForce(transform.forward, ForceMode.Force); } }

物理演算を扱う場合、基本的にはFixedUpdate内に記入。

 Update内だとハード性能によって結果が変わってしまう。

 

・AddForceの()内は

 ( Vector3型 * 任意の値, 任意のフォースモード)で構成。

 力加減はVector3のところに『*』を使う。

 4つあるフォースモードの詳細は外部参照。 

 今回は一瞬だけ力を加える「 VelocityChange 」を使用します。

 

 継続的に力を加えるのではなく一回だけ力を強く加えるので、Fixed内問題は気にしなくていい……ハズ。

その前に

 誰も教えてくれなかったこと。

 

 リジッドボディに力を加えてうんたんする場合。まず大前提として

 

 Drag (抗力)を入れておくこと

 

これが0のままだと減速しない(加えられた力がずっと残ったまま)なので、一旦動かしたら滑り続けるようになります。下のAngularDragは回転に対する抗力です。

 ここ、派手に躓きポイントだと思うんですよね(´・ω・`)

キャラを後方に移動させる力の加え方

Vector3型の変数を使うので

 Vector3. forward、back、right、left、up、down の各Static変数が使える。 

rb.AddForce(Vector3.back * 5.0f, ForceMode.VelocityChange);

 ただしこの場合、奥手前、2P側であってもワールド座標 Vector3(0, 0, -1)から力が加えられるので、必ず同じ方向に動いてしまい3D格ゲー的に欲しい結果が得られず。2P側の向きに注目すると解りやすいです。

 

 -> なので ローカル座標で指定する必要がある 

※注意点

 自分を基準とした向き(ローカル情報)の指定には、Vector3ではなくtransformを使用するが、transformの指定には back、left、down が用意されていないため

× rb.AddForce(transform.back * 5.0f, ForceMode.VelocityChange);

 この書き方だと通らない。


 この場合、正面から負の値をかける ことで後方に飛びます。

rb.AddForce(transform.forward * -5.0f, ForceMode.VelocityChange);

 どの位置からでも自分の後方に移動するようになりました。


 とはいえ『 Vector3.back 』表記がパっと見分かりやすいため、ワールド空間→ローカル空間へ変換する方法も試してみたのですが

rb.AddForce(transform.InverseTransformDirection(Vector3.back) * 5.0f, ForceMode.VelocityChange);

 横軸があってる時の動きは問題ないのですが、位置関係が奥手前にズレると、これも飛んで欲しい方向と違ってしまい上手くいきませんでした。

 

 上記のシンプルなヤツで欲しい挙動は得られているので、深くは掘り下げないことにします。

 『ワールド空間からローカル空間への変換方法がある』という点での覚え書きとして。

 

最後に

 実際に実装する作業より、リジッドボディに関して学習することに時間を費やす結果となってしまいましたが、理解はともかく「仕組み」を把握することは出来たと思います。

 

 これでちゃんと物理的に色々スクリプトで動かせるようになったかと思いきや、Animatorの「 Apply Root Motion 」のオンオフが絡んでくると、これまた瞬間移動とかキャラクターコライダーの判定がおかしくなる不具合出てくるんですよね。

 

 -> その件に関してはこちら

 長い上にgifも多く、正解も解らないのでご容赦を。

 

 

 

 今のところモーションの殆どをblenderで自作してる関係で、移動距離とか含めた大体の動きはアニメーション内に入れちゃってるんですよ。

 

 なので、結局のところ

 

animator.applyRootMotion = true;

 

 した方が不具合少ない気がしてます。

 まぁそれはそれでゲーム画面上で動かして気に入らないときの調整が大変だったりしますが……

 ともあれ、学習したことは無駄にせず、また忘れない為に書き留めておきます。

 とくにリジッドボディのDrag関係の部分とか、初心者向け講座にも全然なかったので、スクリプトで動かす方法だけ紹介 → それを参考にした人が上手くいかない → 原因が分からない → キャラの移動すら思うようにいかない → 挫折、のケース。結構あるんじゃないかと思うんですよ。

 

 ひどい話だなぁと感じたので、自分はちゃんと触れておきます。