# Random.onUnitSphere but within a defined range

I'm trying to instiate a prefabs randomly onUnitSphere, but Instead of instantiating all over the sphere I want them to only instantiate within a small radias on the sphere.

Any Ideas? Thanks - C

Well, `onUnitSphere` is not the right function for this. I would calculate it on my own.

This method is only acceptable for small areas (spot angles). It has a very bad distribution for greater angles (70-90). I just calculate a random point within a unit-circle (radius 1.0). The point get spherically projected onto your sphere. The further away this plane circle is from your sphere center, the smaller the area gets. The tangens just calculates that distance ;).

Here's a sample script. Place it on a gameobject to see the distribution.

``````function GetPointOnUnitSphereCap(targetDirection : Quaternion, angle : float) : Vector3
{
var PointOnCircle = Random.insideUnitCircle;
var V = Vector3(PointOnCircle.x,PointOnCircle.y,distance);
V.Normalize();
return targetDirection*V;
}

var angle : float = 45;

function Update ()
{
for(var i = 0;i<50;i++)
{
var V = GetPointOnUnitSphereCap(transform.rotation,angle);
Debug.DrawRay(transform.position,V,Color.red);
}
}
``````

That's just a simple method that came to my mind. It would be more accurate if you only use angles. I guess that would be even simpler :D

edit

This one has a way better distribution and works up to 180 (full sphere)

``````// UnityScript
function GetPointOnUnitSphereCap(targetDirection : Quaternion, angle : float) : Vector3
{
return targetDirection*V;
}

//C# version
public static Vector3 GetPointOnUnitSphereCap(Quaternion targetDirection, float angle)
{
return targetDirection*V;
}
public static Vector3 GetPointOnUnitSphereCap(Vector3 targetDirection, float angle)
{
return GetPointOnUnitSphereCap(Quaternion.LookRotation(targetDirection), angle);
}
``````

edit

My `GetPointOnUnitSphereCap` function takes a Quaternion to define the direction of the cone (spot) in the same way as the spotlight of unity. The cone always points the the local z-axis. In my example i used the rotation of the gameobject itâ€™s attached to.

To get a point relative to another gameobject just add the point to the position of that gameobject. Since the point my function returns is on the unit-sphere (radius 1.0) you may want to multiply it first with your desired radius.

``````var other : Transform;