Unityで物体同士が接触した際に体が傾くのを無くしたいです。キャラクターや物体が他のオブジェクトと接触すると不自然に傾いてしまう問題を解決する方法を教えてください。
こんにちは!Unityで物体が接触時に傾いてしまう問題は、多くの開発者が直面する一般的な課題です。この問題を解決するための最も効果的な方法の一つが、Rigidbodyのコンストレイント(制約)機能を活用することです。
Rigidbodyコンストレイントは、物理演算が適用されるオブジェクトの動きを特定の軸に沿って制限するための機能です。これにより、物理エンジンの計算に基づく不要な動きを選択的に無効化できます。
// 基本的な使用例
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
// すべての回転を凍結
rb.constraints = RigidbodyConstraints.FreezeRotation;
}
}
キャラクターや物体が全く傾かないようにしたい場合は、すべての回転軸を凍結します。
// すべての回転を凍結
rb.constraints = RigidbodyConstraints.FreezeRotation;
多くのゲームでは、Y軸(垂直軸)を中心とした回転は許可しつつ、X軸とZ軸の回転を防止したい場合があります。
// X軸とZ軸の回転を凍結(Y軸回転のみ許可)
rb.constraints = RigidbodyConstraints.FreezeRotationX |
RigidbodyConstraints.FreezeRotationZ;
場合によっては、回転だけでなく特定の軸の移動も制限したい場合があります。
// Y軸の移動と、X軸とZ軸の回転を凍結
rb.constraints = RigidbodyConstraints.FreezePositionY |
RigidbodyConstraints.FreezeRotationX |
RigidbodyConstraints.FreezeRotationZ;
❌ 悪い例:
// すべての動きを凍結してしまう
rb.constraints = RigidbodyConstraints.FreezeAll;
✅ 改善例:
// 必要な軸のみ凍結する
rb.constraints = RigidbodyConstraints.FreezeRotationX |
RigidbodyConstraints.FreezeRotationZ;
❌ 悪い例:
// 衝突の力を完全に無視してしまう
void OnCollisionEnter(Collision collision) {
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
}
✅ 改善例:
// 衝突後に回転のみリセット
void OnCollisionEnter(Collision collision) {
Vector3 currentRotation = transform.rotation.eulerAngles;
transform.rotation = Quaternion.Euler(0, currentRotation.y, 0);
}
必要最小限の制約を使用する
状況に応じた動的な制約の変更
// 通常時の制約
void SetNormalMovement() {
rb.constraints = RigidbodyConstraints.FreezeRotationX |
RigidbodyConstraints.FreezeRotationZ;
}
isKinematic = true
を設定すると、物理演算が完全に無効化されるため注意が必要ですこの回答は、Unity 2022.3 LTSを基準に作成されています。新しいバージョンでは仕様が変更されている可能性があるため、適宜公式ドキュメントを参照してください。