【Unity】大きな球の表面にキューブを置き、球の中心に向かって重力がかかるようにする
Unityには重力をシミュレートするための物理エンジンが含まれており、それを使用することで簡単に重力を表現できます。
手順概要
以下は、大きな球の表面にキューブを置き、球の中心に向かって重力がかかるようにする方法です。
- まず、大きな球を作成します。これには、Unityの「GameObject」メニューから「3D Object」>「Sphere」を選択します。
- 次に、キューブを作成します。これには、同じく「GameObject」メニューから「3D Object」>「Cube」を選択します。
- キューブを大きな球の表面に置くために、キューブを大きな球の子オブジェクトにします。これには、キューブを選択し、Unityの「Hierarchy」ウィンドウで大きな球の名前の下にドラッグ&ドロップします。
- 重力をシミュレートするために、大きな球に「Rigidbody」コンポーネントを追加します。これにより、大きな球が物理的なオブジェクトとして振る舞い、重力が適用されます。
- 最後に、重力の向きを設定します。大きな球に追加した「Rigidbody」コンポーネントには、「Gravity」フィールドがあります。これを変更して、大きな球の中心に向かって重力がかかるようにします。
以上の手順に従うことで、大きな球の表面にキューブを置き、球の中心に向かって重力がかかるようにすることができます。
サンプル
上記を基本として、Unityで作成してみます
実行結果
シーン構成
Sphere
GameObject(Player)
MainCamera
Cube
スクリプト
CubeGravity
以下のようなC#のコードを使用して、大きな球の表面にキューブを置き、球の中心に向かって重力をシミュレートすることができます。
using UnityEngine;
public class CubeGravity : MonoBehaviour
{
public Transform sphere;
public float gravity = 70f;
private Rigidbody rb;
private void Start()
{
rb = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
Vector3 gravityDirection = (sphere.position - transform.position).normalized;
rb.AddForce(gravityDirection * gravity, ForceMode.Acceleration);
}
}
このスクリプトは、UnityのゲームオブジェクトにアタッチされたCubeGravityコンポーネントによって、別のTransform(ここでは"Sphere"という名前)からの重力をシミュレートするために使用されます。
- publicフィールドとして、sphere(Transform型)、gravity(float型)が宣言されています。ここでは、sphereは重力源となるTransformオブジェクトを参照するための変数であり、gravityは重力の強さを設定するための変数です。
- privateフィールドとして、rb(Rigidbody型)が宣言されています。rbは、このスクリプトがアタッチされたGameObjectのRigidbodyコンポーネントを参照するための変数です。
- Start()関数内では、GetComponent<Rigidbody>()を使用して、このスクリプトがアタッチされたGameObjectのRigidbodyコンポーネントを取得しています。取得したRigidbodyコンポーネントをrb変数に保存します。
- FixedUpdate()関数内では、sphereからの重力方向を計算しています。これは、現在のGameObjectの位置とsphereの位置との距離から計算されます。重力方向は、Normalized()メソッドを使用して正規化され、常に1.0の大きさになります。
- 最後に、rb.AddForce()メソッドを使用して、重力方向と重力の強さを使用してRigidbodyに力を加えます。ForceMode.Accelerationを使用しているため、質量に比例する加速度が加えられます。
MoveCar
using UnityEngine;
public class MoveCar : MonoBehaviour
{
[SerializeField]
float speed;
[SerializeField]
float maxSpeed;
[SerializeField]
float rotationSpeed;
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
float vertical;
void Update()
{
var horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
if (Mathf.Abs(horizontal) > 0.1)
{
transform.Rotate(0, horizontal * rotationSpeed * Time.deltaTime, 0);
}
}
private void FixedUpdate()
{
if (rb.velocity.magnitude < maxSpeed)
{
rb.AddForce(transform.forward * vertical * speed);
}
}
}
[SerializeField]
は、privateなフィールドをInspectorで表示可能にするための属性です。このスクリプトでは、speed
、maxSpeed
、およびrotationSpeed
という3つのprivateな浮動小数点数フィールドがあります。
Rigidbody rb;
は、Rigidbody
コンポーネントへの参照を格納するための変数です。Rigidbodyは、物理演算を適用するためのUnityコンポーネントです。
Start()
メソッドは、スクリプトがアタッチされているGameObjectのRigidbody
コンポーネントへの参照を取得するために使用されます。
float vertical;
は、車の進行方向を決定するための浮動小数点数変数です。
Update()
メソッドは、フレームごとに呼び出されます。このメソッドでは、水平軸および垂直軸の入力を取得しています。水平軸の入力に基づいて、車を回転させる処理が行われます。
FixedUpdate()
メソッドは、物理演算エンジンが実行される間に呼び出されます。このメソッドでは、車を前進させるために、RigidbodyコンポーネントにAddForce()
を使用して力を加えます。加えられる力は、車の進行方向に垂直な方向の力で、vertical
変数に基づいて計算されます。また、車が最大速度に達していない場合にのみ、力が加えられます。
ディスカッション
コメント一覧
まだ、コメントがありません