この記事では、 Unity を使い、任意のオブジェクトを、任意の点を中心に、その周りを周回させる方法について説明します。
使用した Unity のバージョン 2020.1.11f1
使用したOS Windows 10 Home (64bit)
Vector3と、UnityEngine.Mathf.Sin() & Cos() しか使わないので、どのバージョンでも使えます。
これは以前、別のブログに掲載していた記事を手直ししたものです。
// 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# ソースコードにしたものです。