特定のオブジェクトの周りに、オブジェクトをランダム配置させたいという場面に遭遇しました。
今回は、中央にある赤いオブジェクトを起点にし、周囲に適当なオブジェクトを設定する方法について触れます。

数学的なお話
今回は円状に配置するので、ランダムで設定した座標XとYが指定した円の長さの中に含まれるかどうかを判定します。
半径Rの円の中に含まれるかどうかの判定は、次の公式を元にします。
半径の2乗は、X軸の2乗とY軸の2乗を足した値と同じ。
R2 = X2 + Y2
つまり、半径の2乗以内であれば円の中であると言えます。
実装方法
今回はオブジェクトに近すぎる場所には設定ませんのでドーナツ状になります。
ソース
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class circlecontroller : MonoBehaviour {
[Header("分布")]
[SerializeField] Transform CenterPosition; // 対象オブジェクト
[SerializeField] int ArrangementMaxRedius = 1000; // 配置位置の最大半径
[SerializeField] int ArrangementMinRedius = 500; // 配置位置の最小半径
[SerializeField] int ArrangementHeight = 10; // 配置位置の高さ
[Header("個数")]
[SerializeField] GameObject CreaturePrefab; // 対象オブジェクト
[SerializeField] int CreatureLength = 100; // 配置位置の最大
private System.Random random; // 乱数機
// Use this for initialization
void Start () {
GameObject[] CreatureRange = new GameObject[CreatureLength];
random = new System.Random();
int x;
int z;
double xAbs;
double zAbs;
double maxR = Math.Pow(ArrangementMaxRedius, 2);
double minR = Math.Pow(ArrangementMinRedius, 2);
for (int i = 0; i < CreatureRange.Length; i++)
{
while (CreatureRange[i] == null){
x = random.Next(-ArrangementMaxRedius, ArrangementMaxRedius);
z = random.Next(-ArrangementMaxRedius, ArrangementMaxRedius);
xAbs = Math.Abs(Math.Pow(x, 2));
zAbs = Math.Abs(Math.Pow(z, 2));
// 特定の範囲内化確認
if (maxR > xAbs + zAbs && xAbs + zAbs > minR)
{
GameObject go = Instantiate(
CreaturePrefab, // 個体のオブジェクト
(new Vector3(x, ArrangementHeight, z)) + CenterPosition.position, // 初期座標
Quaternion.identity // 回転位置
);
CreatureRange[i] = go;
}
}
}
}
// Update is called once per frame
void Update () {
}
}
実行例
実行すると次のように、中心のオブジェクトに対して周囲にランダム設定されます。

今回は、配置位置が整数型ですが小数型(float)にすればもっときめ細かくなります。
また、3軸を指定すれば円に設定することも出来ます。