こんにちは、ともくんのゲーム作り部屋にようこそ!
このページでは、
「RigidbodyのFreeze Positionってなに?」
「Freeze Positionでどんなことができるの?」
というお悩みの方に向けた内容となっています。
Unityでオブジェクトに物理的挙動を加えられるRigidbodyコンポーネントでは、Freeze Positionという機能を使うことができます。
このFreeze Positionとは、オブジェクトが物理的挙動で移動した際に、特定の軸における移動を防ぐことができる機能になっています。
例えば、オブジェクトに力を加えた際に、上に浮かせたくないといった場合などに使用します。
そこで、このページでは、UnityのRigidbodyコンポーネントにあるFreeze Positionという機能について、どんな機能なのか、また使い方までをまとめていきます。
Freeze Positionとは?Rigidbodyによる移動を制御できる機能
まずは、Freeze Positionがどういうものなのかを紹介していきます。
Freeze Positionとは、Rigidbodyコンポーネントが付いているオブジェクトに対して、特定の軸における移動を防止することができる機能です。
Rigidbodyを付けたオブジェクトは、AddForceメソッドなどを使って力を加えて移動させることができますが、想定していない動きになってしまうことがあり、その際にFreeze Positionを使うことで移動を制御することができます。
例えば、以下のようにオブジェクトに力を加えて移動させようとした際に、オブジェクトが浮いてしまうということがあります。

オブジェクトは移動させたいけど、宙に浮かせたくないというような場合に、Freeze PositionでY軸への移動を防止するようにしてあげます。

すると、上記のようにオブジェクトを浮かせずに、移動させることができるようになります。
Freeze Positionの使い方
ここからは、Freeze Positionの使い方について紹介していきます。
インスペクターウィンドウから設定する
Freeze Positionを設定する場合は、オブジェクトを選択してインスペクターウィンドウから、RigidbodyコンポーネントのConstraintsの中にあるFreeze Positionで設定していきます。

具体的には、
というように、オブジェクトの移動を防止したい軸をチェックすることで、その軸の移動を防ぐことができます。
例えば、Rigidbodyを付けた赤い球形のオブジェクトに、青いキューブオブジェクトを衝突させて動かしているとします。

この衝突させられている赤いオブジェクトのFreeze PositionのXにチェックを入れると、衝突した後のX軸への移動が防止され、Z軸側に向かって移動するようになります。

また、Freeze PositionのZにチェックを入れると、Z軸の移動を防止することができ、X軸側に移動するという全く異なる挙動を作ることができます。

なお、2Dゲームで使うRigidbody2Dでは、Freeze Positionで指定できる軸はXとYだけとなっています。

スクリプトから設定する
Freeze Positionの設定は、インスペクターウィンドウからだけでなくスクリプトから設定することもできます。
なお、スクリプトから設定する場合は先にRigidbodyコンポーネントをGetComponentメソッドなどで取得しておく必要があります。
Freeze PositionのXを設定する
スクリプトからFreeze PositionのXを設定したい場合は、
Rigidbody.constraints = RigidbodyConstraints.FreezePositionX;もしくは、
Rigidbody2D.constraints = RigidbodyConstraints2D.FreezePositionX;と記述していきます。
例えば、
using UnityEngine;
public class Test1 : MonoBehaviour
{
Rigidbody rb; // Rigidbody型の変数を宣言
void Start()
{
rb = GetComponent<Rigidbody>(); // Rigidbodyコンポーネントを取得
rb.constraints = RigidbodyConstraints.FreezePositionX; // FreezePositionのXを設定する
}
}上記のように、Startメソッドの中の10行目で処理を記述しておくことで、ゲームを実行したタイミングで、Freeze PositionのXが設定されているのが分かります。
<ゲーム実行前>

<ゲーム実行後>

Freeze PositionのYを設定する
スクリプトからFreeze PositionのYを設定したい場合は、
Rigidbody.constraints = RigidbodyConstraints.FreezePositionY;もしくは、
Rigidbody2D.constraints = RigidbodyConstraints2D.FreezePositionY;と記述していきます。
例えば、スペースキーを押してFreeze PositionのYを設定する処理を作る場合、
using UnityEngine;
public class Test : MonoBehaviour
{
Rigidbody2D rb; // Rigidbody型の変数を宣言
void Start()
{
rb = GetComponent<Rigidbody2D>(); // Rigidbodyコンポーネントを取得
}
void Update()
{
// スペースキーを押した場合
if (Input.GetKeyDown(KeyCode.Space))
{
rb.constraints = RigidbodyConstraints2D.FreezePositionY; // FreezePositionのYを設定する
}
}
}上記のように、17行目で処理を記述しておくことで、スペースキーを押したらY軸の移動が防止されるようになります。
これを使えば、以下のようにオブジェクトが地面で跳ねている途中の段階で動きを止めるといったこともできるようになります。

Freeze PositionのZを設定する
スクリプトからFreeze PositionのZを設定したい場合は、
Rigidbody.constraints = RigidbodyConstraints.FreezePositionZ;もしくは、
Rigidbody2D.constraints = RigidbodyConstraints2D.FreezePositionZ;と記述していきます。
例えば、特定のオブジェクトと衝突したら、Freeze Position Zを設定したいというような場合は、
using UnityEngine;
public class Test : MonoBehaviour
{
Rigidbody rb; // Rigidbody型の変数を宣言
public GameObject target; // ターゲットとなるオブジェクトを取得
void Start()
{
rb = GetComponent<Rigidbody>(); // Rigidbodyコンポーネントを取得
rb.AddForce((target.transform.position - this.transform.position) * 150f); // ターゲットに向かって力を加える
}
void OnCollisionEnter(Collision collision)
{
// ターゲットに衝突した場合
if (collision.gameObject == target)
{
rb.constraints = RigidbodyConstraints.FreezePositionZ; // FreezePositionのZを設定する
}
}
}上記のように、衝突したことを検知するOnCollisionメソッド内の19行目で処理を記述しておくことで、衝突前はZ軸へ移動していた青いオブジェクトが、衝突後はX軸にだけ移動しているのが分かります。

Freeze Positionの全ての軸を設定する
Freeze Positionの全ての軸をスクリプトから設定することもできます。
その場合は、
Rigidbody.constraints = RigidbodyConstraints.FreezePosition;もしくは、
Rigidbody2D.constraints = RigidbodyConstraints2D.FreezePosition;例えば、以下のスクリプトをオブジェクトにアタッチしておきます。
using UnityEngine;
public class Test : MonoBehaviour
{
Rigidbody rb; // Rigidbody型の変数を宣言
void Start()
{
rb = GetComponent<Rigidbody>(); // Rigidbodyコンポーネントを取得
rb.constraints = RigidbodyConstraints.FreezePosition; // 全ての軸のFreezePositionを設定する
}
}Startメソッド内の10行目で、全てのFreeze Positionを設定することで、ゲーム実行時に処理が実行されて、全ての軸への移動が防止されているのが分かります。
<ゲーム実行前>

<ゲーム実行後>

Freeze Positionの設定を解除する
スクリプトからFreeze Positionの設定を解除する場合は、
Rigidbody.constraints = RigidbodyConstraints.None;もしくは、
Rigidbody2D.constraints = RigidbodyConstraints2D.None;と記述することで解除できます。
ただし、constraintsの中の設定を全て解除することになるため、全ての軸のFreeze Positionの設定が解除されて、また回転を防止することができるFreeze Rotationの設定も解除されることになります。
例えば、スペースキーを押したらFreeze Positionの設定を全て解除するという処理を作る場合、
using UnityEngine;
public class Test : MonoBehaviour
{
Rigidbody rb; // Rigidbody型の変数を宣言
void Start()
{
rb = GetComponent<Rigidbody>(); // Rigidbodyコンポーネントを取得
}
void Update()
{
// スペースキーを押した場合
if (Input.GetKeyDown(KeyCode.Space))
{
rb.constraints = RigidbodyConstraints.None; // Constraintsの設定を全て無しにする
}
}
}17行目のように記述してあげることで、Freeze Positionの設定を解除することができます。
まとめ
このページでは、UnityのRigidbodyコンポーネントで使えるFreeze Positionという機能について、どういうものなのか、また使い方までをまとめていきましたが、いかがでしたでしょうか?
Freeze Positionとは、Rigidbodyの付いたオブジェクトが移動される際に、特定の軸における移動を防止することができる設定です。
このFreeze Positionを使うことで、Rigidbodyのオブジェクトが想定していない動きや移動をしないように制御することができます。
Freeze Positionを設定する際は、インスペクターウィンドウから設定するか、スクリプト内で記述することで、特定のタイミングでFreeze Positionの設定を行うことができます。
最後までお読みいただきまして、ありがとうございました!







コメント