こんにちは、ともくんのゲーム作り部屋にようこそ!
このページでは、
「UnityのlinearVelocityってなに?」
「オブジェクトの速度を取得したい!」
というお悩みの方に向けた内容となっています。
Unityでは、Rigidbodyコンポーネントを使ってオブジェクトに力を与えることができますが、その際にlinearVelocityという変数を使うことができます。
このlinearVelocityとは、Rigidbodyの付いたオブジェクトのそれぞれの軸に対しての線形速度の値をVector型で取得することができる変数です。
linearVelocityを使うことで、オブジェクトが今動いているのか、どの位の速度で動いているのか、またどの向きに動いているのか、などが分かるようになります。
そこでこのページでは、UnityのRigidbodyコンポーネントで使うことができるlinearVelocityについて、どんな変数なのか、また使い方までをまとめていきます。
linearVelocityとは?
まずは、linearVelocityがどういう変数なのかについて紹介していきます。
各軸に対する線形速度のベクトルを取得できる変数
linearVelocityとは、各軸に対しての線形速度をVector型で取得することができるRigidbodyコンポーネントで管理されている変数です。
もう少し具体的に言うと、linearVelocityはX軸・Y軸・Z軸のそれぞれの直線方向に対して、オブジェクトがどのくらいの速度で進んでいるのかを表していて、現在のそれぞれの速度をVector型で取得することができます。

また、軸の進行方向に進んでいる場合は正の速度の値となり、軸の進行方向と反対に向かう場合は負の速度の値となります。
例えば、プレイヤーがジャンプするという処理を作った場合、ジャンプし始めた時はY軸の進行方向に向かっていくので、Y軸の速度は正の値を取得できますが、降りてくるときはY軸と反対に下向きになるので、Y軸の速度は負の値となります。

なお、RigidbodyコンポーネントやVector構造体については、以下の記事も参考にしてみてください。
速度制限やオブジェクトの動きを監視するのに使う
linearVelocityを使うことで、オブジェクトに対して速度制限を行ったり、オブジェクトの動きを監視するといったことができるようになります。
例えば、車のオブジェクトを作りRigidbodyで力を加えて動かすといった場合、力を常に加え続けてしまうと、車の速度がどんどんと上がってしまうことになります。
そこで、linearVelocityを使って車の速度を取得し、特定の速度を超えたら力を加えなくなるようにしてあげれば、車に対して速度制限の仕組みを作ることができます。

他にも、linearVelocityの数値が増えている場合などは、オブジェクトが動いているということが判断できるので、ゲーム内での条件分岐を使った処理などで使うことができます。
注意点:基本的に値を変動させない
linearVelocityに値を代入することで、オブジェクトの動いている速度を変えたり、オブジェクトを動かすといったこともできます。
しかし、基本的にはこのような使い方はせず、公式でも推奨されていません。
なぜなら、オブジェクトを動かすという処理は、Rigidbody内で物理演算を使い、より自然にオブジェクトが動くように処理されているからです。
仮にlinearVelocityの値を変動させてしまうと、この物理的な挙動を無視した動きになってしまうことになります。
そのため、linearVelocityの値は基本的に変更などは行いません。
もしオブジェクトを動かしたり速度を変えたいという場合は、オブジェクトに力を加えるAddForceメソッドで変化を加えるようにしましょう。
linearVelocityの使い方
ここからは、実際にUnity内でのlinearVelocityの使い方を紹介していきます。
Rigidbody.linearVelocityで線形速度のベクトルを取得する
オブジェクトに対して、線形速度のベクトルを取得する場合は、Rigidbodyコンポーネントを使って、
Rigidbody.linearVelocity
と記述することで取得できます。
例えば、キー操作でオブジェクトに力を加えて移動させる処理を作り、さらにスペースキーを押すと線形速度のベクトルが取得できるという処理を作ってみます。
using UnityEngine;
public class CubeController : MonoBehaviour
{
Rigidbody rb;
float power = 3.5f; // 加える力の変数
void Start()
{
rb = GetComponent<Rigidbody>(); // Rigidbodyコンポーネントを取得する
}
void Update()
{
// キー操作による力を加える処理
if (Input.GetKey(KeyCode.W))
{
rb.AddForce(transform.forward * power);
}
if (Input.GetKey(KeyCode.S))
{
rb.AddForce(-transform.forward * power);
}
if (Input.GetKey(KeyCode.D))
{
rb.AddForce(transform.right * power);
}
if (Input.GetKey(KeyCode.A))
{
rb.AddForce(-transform.right * power);
}
// スペースキーを押した場合
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log(rb.linearVelocity); // 線形速度のベクトルを取得して表示する
}
}
}
15行目から31行目まで、キー操作でAddForceメソッドを使いオブジェクトに力を加える処理を記述しています。
linearVelocityを使用する場合、10行目のようにGetComponentメソッドなどで、先にRigidbodyコンポーネントを取得しておく必要があります。
そして、スペースキーを押した場合の中の36行目で、「Rigidbody.linearVelocity」と記述してあげることで、線形速度のベクトルをVector型で取得することができます。
実際に、オブジェクトに力を加えて、特定の地点での速度ベクトルを取得してみると、

それぞれVector型で線形速度が表示されているのが分かります。
また、それぞれの軸における速度を取得したい場合は、以下のように書くこともできます。
using UnityEngine;
public class CubeController : MonoBehaviour
{
Rigidbody rb;
float power = 3.5f; // 加える力の変数
void Start()
{
rb = GetComponent<Rigidbody>(); // Rigidbodyコンポーネントを取得する
}
void Update()
{
// キー操作による力を加える処理
if (Input.GetKey(KeyCode.W))
{
rb.AddForce(transform.forward * power);
}
if (Input.GetKey(KeyCode.S))
{
rb.AddForce(-transform.forward * power);
}
if (Input.GetKey(KeyCode.D))
{
rb.AddForce(transform.right * power);
}
if (Input.GetKey(KeyCode.A))
{
rb.AddForce(-transform.right * power);
}
// スペースキーを押した場合
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("X軸の速度:" + rb.linearVelocity.x); // X軸における線形速度の値
Debug.Log("Y軸の速度:" + rb.linearVelocity.y); // Y軸における線形速度の値
Debug.Log("Z軸の速度:" + rb.linearVelocity.z); // Z軸における線形速度の値
}
}
}
36行目から38行目のように「linearVelocity.x」「linearVelocity.y」「linearVelocity.z」の変数をそれぞれ使うことで、軸に対する線形速度を取得することができます。
こちらも実際にオブジェクトに力を加えてみると、

それぞれの軸に対する速度を取り出すことができています。
linearVelocityの実用例
ここからはlinearVelocityを使用した実用例として、
といった処理を作ってみます。
3Dでオブジェクトの速度制限を行う
linearVelocityを使うことで、オブジェクトの移動速度を制限することができます。
ここでは、3Dゲームで以下の青いオブジェクトに力を加えて移動させ、その移動速度を制限する処理を作ってみます。

オブジェクトにRigidbodyコンポーネントを付けて、以下のスクリプトをアタッチします。
using UnityEngine;
public class CubeController : MonoBehaviour
{
Rigidbody rb;
float maxSpeed = 10.0f; // 最高速度の変数
float speed; // 現在のスピードを取得する変数
float power = 3.5f; // 加える力の変数
void Start()
{
rb = GetComponent<Rigidbody>(); // Rigidbodyコンポーネントを取得する
}
void Update()
{
speed = rb.linearVelocity.magnitude; // 現在の速度を取得
// 最高速度より現在の速度が低い場合
if (speed < maxSpeed)
{
// キー操作による力を加える処理
if (Input.GetKey(KeyCode.W))
{
rb.AddForce(transform.forward * power);
}
if (Input.GetKey(KeyCode.S))
{
rb.AddForce(-transform.forward * power);
}
if (Input.GetKey(KeyCode.D))
{
rb.AddForce(transform.right * power);
}
if (Input.GetKey(KeyCode.A))
{
rb.AddForce(-transform.right * power);
}
}
}
}
linearVelocityで取得する線形速度のベクトルから、オブジェクトの速度を取得する場合は、17行目のようにベクトルの長さを表すmagnitudeという変数を使うことで、簡単に取得できます。
このmagnitudeとは、Vectorの構造体が持つ変数で、「Vector.magnitude」と記述することで、ベクトルの長さを取得することができます。
そして、20行目以降で現在の速度が10.0以下の時にのみAddForceメソッドで力を加えるという処理を作っています。
実際にゲームを実行してみると、

最初は少しずつ力が加わり速度が上がっていきますが、速度が10.0以上になると力が加わらなくなり、速度制限を作ることができています。
2Dでオブジェクトの速度制限を行う
先ほどは3Dゲームで速度制限の処理を作りましたが、次は2Dゲームでも作ってみます。
以下のオレンジ色のオブジェクトに対してRigidbody2Dを付けて、矢印キーで右と左に力を加える処理を行います。

using UnityEngine;
public class SquareController : MonoBehaviour
{
Rigidbody2D rb;
float maxSpeed = 8.0f; // 最高速度の変数
float speed; // 現在の速度の変数
float power = 3.0f;
void Start()
{
rb = GetComponent<Rigidbody2D>(); // Rigidbody2Dコンポーネントを取得する
}
void Update()
{
speed = Mathf.Abs(rb.linearVelocity.x); // X軸における現在の速度を絶対値で取得する
// 最高速度より現在の速度が低い場合
if (speed < maxSpeed )
{
// キー操作で力を加える処理
if (Input.GetKey(KeyCode.RightArrow))
{
rb.AddForce(transform.right * power);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
rb.AddForce(-transform.right * power);
}
}
}
}
2Dの場合はZ軸が無いため、「linearVelocity.x」でX軸における速度を取得することができます。
ただし、オブジェクトが反対方向に進む際は負の値となるため、17行目でMathf.Absというメソッドを使って負の符号を取る処理をしています。
このMathf.Absは、引数に指定した値の絶対値を返してくれるメソッドで、正の値であればそのままですが、負の値の場合はマイナスが取れた値が返ってくることになります。
あとは、先ほどと同じように20行目で速度制限の処理を作っています。
ゲームを実行してみると、

X軸のどちらの向きに対しても、速度制限がかかるようになっています。
ジャンプしているかどうかを判定する
linearVelocityは速度制限だけでなく、オブジェクトが動いているかどうかを判定することもできます。
ここでは、先ほどと同じ以下のオレンジのオブジェクトがスペースキーを押すとジャンプできる処理を作り、ジャンプ中の場合はスペースキーを押しても、以下のように連続でジャンプできないようにする処理をlinearVelocityで作ってみます。

プレイヤーにRigidbodyコンポーネントを紐づけて、以下のスクリプトをアタッチします。
using UnityEngine;
public class SquareController : MonoBehaviour
{
Rigidbody2D rb;
float jumpPower = 500.0f;
void Start()
{
rb = GetComponent<Rigidbody2D>(); // Rigidbody2Dコンポーネントを取得する
}
void Update()
{
// Y軸の速度が0の場合
if (rb.linearVelocity.y == 0)
{
// スペースキーでジャンプする処理を行う
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(transform.up * jumpPower);
}
}
}
}
プレイヤーがジャンプしている場合は、Y軸において移動しているため、Y軸の線形速度が変動することになります。
そのため、16行目で「linearVelocity.y」の値が0の時にのみ、プレイヤーがジャンプできるという処理を作っています。
linearVelocity.yが0ということは、Y軸に対して移動していない、つまりジャンプしていないということになります。
実際にゲームを実行してみると、

プレイヤーがすでにジャンプしているときは、スペースキーを押してもジャンプができなくなっています。
なお、ジャンプしているかどうかを判定する際は、linearVelocityだけでなく、床との当たり判定を使った接地判定を作る場合もあります。
まとめ
このページでは、UnityのRigidbodyコンポーネントで使うことができるlinearVelocityという変数について、どんな変数なのか、また使い方や実用例までをまとめていきましたが、いかがでしたでしょうか?
linearVelocityとは、オブジェクトの直線移動である線形速度のベクトルを取得することができる変数です。
linearVelocityを使うことで、オブジェクトの速度制限を作ったり、オブジェクトが動いているかどうかを判定することができます。
また、magnitudeを使ってあげることで、オブジェクトの速度をゲーム内に表示させたりすることもできます。
最後までお読みいただきまして、ありがとうございました!
コメント