【Unity】大きな球の表面にキューブを置き、球の中心に向かって重力がかかるようにする

Unityには重力をシミュレートするための物理エンジンが含まれており、それを使用することで簡単に重力を表現できます。

手順概要

以下は、大きな球の表面にキューブを置き、球の中心に向かって重力がかかるようにする方法です。

  1. まず、大きな球を作成します。これには、Unityの「GameObject」メニューから「3D Object」>「Sphere」を選択します。
  2. 次に、キューブを作成します。これには、同じく「GameObject」メニューから「3D Object」>「Cube」を選択します。
  3. キューブを大きな球の表面に置くために、キューブを大きな球の子オブジェクトにします。これには、キューブを選択し、Unityの「Hierarchy」ウィンドウで大きな球の名前の下にドラッグ&ドロップします。
  4. 重力をシミュレートするために、大きな球に「Rigidbody」コンポーネントを追加します。これにより、大きな球が物理的なオブジェクトとして振る舞い、重力が適用されます。
  5. 最後に、重力の向きを設定します。大きな球に追加した「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"という名前)からの重力をシミュレートするために使用されます。

  1. publicフィールドとして、sphere(Transform型)、gravity(float型)が宣言されています。ここでは、sphereは重力源となるTransformオブジェクトを参照するための変数であり、gravityは重力の強さを設定するための変数です。
  2. privateフィールドとして、rb(Rigidbody型)が宣言されています。rbは、このスクリプトがアタッチされたGameObjectのRigidbodyコンポーネントを参照するための変数です。
  3. Start()関数内では、GetComponent<Rigidbody>()を使用して、このスクリプトがアタッチされたGameObjectのRigidbodyコンポーネントを取得しています。取得したRigidbodyコンポーネントをrb変数に保存します。
  4. FixedUpdate()関数内では、sphereからの重力方向を計算しています。これは、現在のGameObjectの位置とsphereの位置との距離から計算されます。重力方向は、Normalized()メソッドを使用して正規化され、常に1.0の大きさになります。
  5. 最後に、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で表示可能にするための属性です。このスクリプトでは、speedmaxSpeed、およびrotationSpeedという3つのprivateな浮動小数点数フィールドがあります。

Rigidbody rb;は、Rigidbodyコンポーネントへの参照を格納するための変数です。Rigidbodyは、物理演算を適用するためのUnityコンポーネントです。

Start()メソッドは、スクリプトがアタッチされているGameObjectのRigidbodyコンポーネントへの参照を取得するために使用されます。

float vertical;は、車の進行方向を決定するための浮動小数点数変数です。

Update()メソッドは、フレームごとに呼び出されます。このメソッドでは、水平軸および垂直軸の入力を取得しています。水平軸の入力に基づいて、車を回転させる処理が行われます。

FixedUpdate()メソッドは、物理演算エンジンが実行される間に呼び出されます。このメソッドでは、車を前進させるために、RigidbodyコンポーネントにAddForce()を使用して力を加えます。加えられる力は、車の進行方向に垂直な方向の力で、vertical変数に基づいて計算されます。また、車が最大速度に達していない場合にのみ、力が加えられます。

Unity,学習

Posted by hidepon