【Unity】オブジェクトAの周りを廻るオブジェクトB
オブジェクトBがオブジェクトAの周りを等速で回転し、常にオブジェクトAを見ているスクリプトは以下のように作成できます。このスクリプトをオブジェクトBにアタッチします


using UnityEngine;
public class OrbitAround : MonoBehaviour
{
public Transform target; // オブジェクトAのTransform
public float orbitSpeed = 10f; // 回転速度
public float distance = 5f; // 回転半径
void Update()
{
// オブジェクトAを中心にオブジェクトBを回転させる
Orbit();
// オブジェクトBが常にオブジェクトAを向くようにする
LookAtTarget();
}
void Orbit()
{
// 時間に基づいてオブジェクトBの新しい位置を計算
float angle = orbitSpeed * Time.deltaTime;
transform.RotateAround(target.position, Vector3.up, angle);
// オブジェクトBをターゲットから一定の距離に維持
Vector3 direction = transform.position - target.position;
direction.Normalize();
transform.position = target.position + direction * distance;
}
void LookAtTarget()
{
transform.LookAt(target);
}
}
using UnityEngine;
/// <summary>
/// 指定した「target」を中心に、指定距離だけ離れて円形移動(回転)させるスクリプト。
/// Inspector 上で「初期角度(0~360°)」を設定することで、複数体を等間隔に配置可能。
/// </summary>
public class OrbitAround : MonoBehaviour
{
[Header("――――――――――――――――――――――――")]
[Header("〈回転の中心〉")]
[Tooltip("回転の中心となる Transform。シーン上の任意のオブジェクトを指定できます。")]
public Transform target;
[Header("〈回転に関する設定〉")]
[Tooltip("中心の周りを回る速さ(度/秒)。Inspector では度 (°) 単位で指定。")]
public float orbitSpeed = 60f;
[Tooltip("回転半径(中心からの距離)。")]
public float distance = 2.0f;
[Header("〈配置オフセット〉")]
[Range(0f, 360f)]
[Tooltip("このオブジェクトの初期角度(度)。\n" +
"例:0, 120, 240 をそれぞれ設定すると等間隔に配置されます。")]
public float initialAngle = 0f;
// 内部で扱うラジアン表現の角度
private float _angleRad;
void Start()
{
if (target == null)
{
Debug.LogError("[OrbitAround] target が設定されていません。Inspector で中心にしたいオブジェクトの Transform をセットしてください。");
enabled = false;
return;
}
// Inspector で指定された「初期角度(度)」をラジアンに変換
_angleRad = initialAngle * Mathf.Deg2Rad;
// 初期フレーム時に位置を更新
UpdatePosition();
}
void Update()
{
if (target == null) return;
// 毎フレーム、orbitSpeed (°/s) をラジアンに変換して角度を加算
float deltaAngleRad = orbitSpeed * Time.deltaTime * Mathf.Deg2Rad;
_angleRad += deltaAngleRad;
// 位置更新
UpdatePosition();
}
/// <summary>
/// _angleRad と距離 distance を使って transform.position を更新する
/// </summary>
private void UpdatePosition()
{
// 回転平面は XY 面を想定。Z はそのまま維持。
float x = target.position.x + Mathf.Cos(_angleRad) * distance;
float y = target.position.y + Mathf.Sin(_angleRad) * distance;
float z = transform.position.z;
transform.position = new Vector3(x, y, z);
// 中心オブジェクトを常に向きたい場合は以下を有効化:
// transform.up = (target.position - transform.position).normalized;
}
}
プレハブ化した Enemy に OrbitAround スクリプトをあらかじめアタッチしておき、スクリプトで一括生成して等間隔に配置したい場合は、以下のように EnemySpawner クラスを用意すると便利です。
using UnityEngine;
/// <summary>
/// 指定した「target」を中心に、設定した数の Enemy を一括生成し、等間隔で回転させるサンプルスクリプト。
/// Prefab(EnemyOrbitPrefab)にはあらかじめ OrbitAround がアタッチされている想定。
/// </summary>
public class EnemySpawner : MonoBehaviour
{
[Header("――――――――――――――――――――――――")]
[Header("〈生成に関する設定〉")]
[Tooltip("回転の中心になるオブジェクトの Transform をセット")]
public Transform target;
[Tooltip("OrbitAround がアタッチされた敵のプレハブ")]
public GameObject enemyOrbitPrefab;
[Tooltip("生成する敵の数(例:3 を指定すると 360/3 = 120° 間隔になります)")]
[Range(1, 12)]
public int enemyCount = 3;
[Tooltip("回転半径")]
public float distance = 2.0f;
[Tooltip("回転速度(度/秒)」)
public float orbitSpeed = 60f;
void Start()
{
if (target == null || enemyOrbitPrefab == null)
{
Debug.LogError("[EnemySpawner] target または enemyOrbitPrefab が未設定です。");
return;
}
// 等間隔に配置するための角度ステップ(度)
float angleStep = 360f / enemyCount;
for (int i = 0; i < enemyCount; i++)
{
// Prefab を target の位置に生成
GameObject enemy = Instantiate(enemyOrbitPrefab, target.position, Quaternion.identity);
// OrbitAround コンポーネントを取得
OrbitAround orbitComp = enemy.GetComponent<OrbitAround>();
if (orbitComp == null)
{
Debug.LogWarning("[EnemySpawner] 生成したプレハブに OrbitAround がアタッチされていません。");
continue;
}
// 各パラメータを設定
orbitComp.target = target;
orbitComp.distance = distance;
orbitComp.orbitSpeed = orbitSpeed;
orbitComp.initialAngle = i * angleStep; // 例:0°, 120°, 240°
}
}
}
訪問数 31 回, 今日の訪問数 1回
ディスカッション
コメント一覧
まだ、コメントがありません