Unity2Dゲームで「円(球体)の外側を歩く」みたいな感じのを実装していきます。地球の周りを回る月とかにも使えそうな惑星の動きみたいな感じですね。
はじめに
Unityのバージョンは2021.3.14f1です。
オブジェクトを回転させるQuaternionを利用していきます。
実装開始
2パターンで作成していきます。
円の周りを動く
Hierarchyで右クリック、「2DObject」→「Sprites」→「Circle」を追加。

名前をPlanetに変更し、下記のような感じにスケールを色を変更します。

配下に「2DObject」→「Sprites」→「Square」を追加。名前をSurfaceにし、位置とスケールを変更します。

下記のような感じですね。この状態で円(Planet)ごと回転させて円の周りを動くようにします。

スクリプトの作成
Surfaceという名前でスクリプトを作成。中身を下記にします。キーボード入力でオブジェクトを回転させます。
using UnityEngine; public class Surface : MonoBehaviour { [SerializeField] private Transform _transform; private float _rotateSpeed = 30.0f; private float angle; private void Update() { float InputX = Input.GetAxisRaw("Horizontal"); if (InputX != 0) { angle -= _rotateSpeed * InputX * Time.deltaTime; _transform.rotation = Quaternion.Euler(0, 0, angle); } } }
Surfaceにスクリプトをアタッチして、パラメータをセット。

実行してキー入力すると下記のように動きます。

重力があるような動き
次は重力で周りを動いている感じにしてみます。
Planetに「CircleCollider2D」をアタッチ。

Surfaceに「BoxCollider2D」と「Rigidbody2D」をアタッチ、「GravityScale」を0にします。

Surfaceスクリプトの中身を下記に変更します。円の中心と自身の位置から方向を算出して重力を加えています。
using UnityEngine; public class Surface : MonoBehaviour { [SerializeField] private Transform planet; private Rigidbody2D _rigidbody; private float Gravity = 100.0f; private float moveSpeed = 5.0f; private void Awake() { _rigidbody = GetComponent<Rigidbody2D>(); } private void Update() { Vector2 distance = planet.transform.position - transform.position; _rigidbody.AddForce(distance.normalized * Gravity); float InputX = Input.GetAxisRaw("Horizontal"); if (InputX != 0) _rigidbody.velocity = transform.up * moveSpeed * InputX; else _rigidbody.velocity = new Vector2(0f, 0f); float angle = Mathf.Atan2(distance.y, distance.x) * Mathf.Rad2Deg; transform.rotation = Quaternion.Euler(0, 0, angle); } }
実行すると下記のような感じに動きます。
