【Unity】ある点の周りを周回させる方法

この記事では、 Unity を使い、任意のオブジェクトを、任意の点を中心に、その周りを周回させる方法について説明します。

使用した Unity のバージョン 2020.1.11f1
使用したOS Windows 10 Home (64bit)

Vector3と、UnityEngine.Mathf.Sin() & Cos() しか使わないので、どのバージョンでも使えます。


これは以前、別のブログに掲載していた記事を手直ししたものです。

C# ソースコード(Unity用)
// X軸回転
static Vector3 RotateAroundX(Vector3 original_position, float angle, float radius)
{
   Vector3 v = original_position;
   v.z += radius;
   float a = angle * Mathf.Deg2Rad;
   float x = v.x;
   float y = Mathf.Cos(a) * v.y - Mathf.Sin(a) * v.z;
   float z = Mathf.Sin(a) * v.y - Mathf.Cos(a) * v.z;
   return new Vector3(x, y, z);
}

// Y軸回転
static Vector3 RotateAroundY(Vector3 original_position, float angle, float radius)
{
   Vector3 v = original_position;
   v.z += radius;
   float a = angle * Mathf.Deg2Rad;
   float x = Mathf.Cos(a) * v.x + Mathf.Sin(a) * v.z;
   float y = v.y;
   float z = -Mathf.Sin(a) * v.x + Mathf.Cos(a) * v.z;
   return new Vector3(x, y, z);
}

// Z軸回転
static Vector3 RotateAroundZ(Vector3 original_position, float angle, float radius)
{
   Vector3 v = original_position;
   v.y += radius;
   float a = angle * Mathf.Deg2Rad;
   float x = Mathf.Cos(a) * v.x - Mathf.Sin(a) * v.y;
   float y = Mathf.Sin(a) * v.x + Mathf.Cos(a) * v.y;
   float z = v.z;
   return new Vector3(x, y, z);
}

何故この計算でできるのか?は分かりません。

使い方
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
   public float angle = 0.0f;
   public float radius = 2.0f;
   public GameObject center = null;

   // Update is called once per frame
   void Update()
   {
      this.transform.position = RotateAroundY(this.center.transform.position, this.angle, this.radius);
      this.angle += 0.01f;
   }

   static Vector3 RotateAroundY(Vector3 original_position, float angle, float radius)
   { /* 省略 */ }
}

こんな感じのスクリプトを用意します。

Y軸で周回させたい場合は、RotateAroundY() を使います。
上記のサンプルコードのように、周回させたいオブジェクトのスクリプトにRotateAroundY() をコピペします。


周りをグルグル回られちゃう、周回の中心となるオブジェクトを、インスペクターで指定しておきます。
上記のサンプルコードの center がそれにあたります。

radius は、中心となるオブジェクトから、どれくらい距離をとるか?を指定します。
すぐ近くを周回させたいなら小さい値にして、距離をとって周回させたいなら大きい値にします。

あとは、Update() で angle を足すなり引くなりすれば、angle に合わせて周回します。


2Dゲームなら、こういうことをするのに必要です。
オプションとか使い魔とか、よくあるやつですね。

複数の軸で周回させる
   public float radius_x = 1.0f;
   public float radius_y = 0.5f;
   float angle_x = 0.0f;
   float angle_y = 0.0f;
   void Update()
   {
      Vector3 x = RotateAroundX(this.center.transform.position, this.angle_x, this.radius_x);
      Vector3 y = RotateAroundY(this.center.transform.position, this.angle_y, this.radius_y);
      this.transform.position = x + y;
      this.angle_x += 0.01f;
      this.angle_y += 0.05f;
   }

それぞれの計算結果を足して、transform.position に代入するだけです。
angle の変化量、radius の値をバラバラにすると、かなり複雑な軌道で周回するようになります。

記事を書くに至った経緯

この計算はゲームでわりと使いますが、計算方法が一発で分かるブログ記事を見ません。
よく探せばあるんだとは思いますが、よく探す時間がもったいないです。
なので、自分のブログに書いておくことにしました。
私自身がちょこちょこ使っているくらいなので、ゲーム制作をしておられる私以外の方にも、きっと役に立つはずです。

この記事のサンプルコードは、こちらに掲載されている計算式を、Unity 用の C# ソースコードにしたものです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です