- Home /
Randomly Instantiating an object inside a shrinking sphere?
I'm currently creating a game where the player has to collect orbs with a spaceship while inside a shrinking sphere, when an orb is collected it needs to instantiate again and increase the size of the sphere. What I need help with is how to go about doing this, I've worked out what I think needs to happen but I'm still learning.
The code also would need to perform a raycast to not instantiate inside any planets and shrink the Random.insideUnitSphere's radius with the sphere the solar system is inside of so the player can't helplessly lose.
I have this for shrinking the sphere
var startScale = Vector3.one;
var endScale = Vector3.zero;
var t = 0.0;
var speed = .5;
while (t < 1)
{
t += Time.deltaTime * speed;
position = transform.localScale = Vector3.Lerp(startScale, endScale, t);
yield;
}
but I think I might need to make it increase in speed over time too to add some difficulty.
Thank you for reading this far any assistance will be more than grateful, I'm just unsure of the best way to do all this is.
Answer by robertbu · Aug 09, 2013 at 05:42 AM
From your description, I see two separate technical problems. The first is how to randomly spawn your target inside the large (but shrinking) sphere. The second problem is how to avoid spawning a target on top of a 'planet'.
The radius of the outside sphere will be half of the local scale of x,y, or z. I'll call this radiusOuter. The target will also have a radius that is half of the local scale of the target. To find a potential position to place the target you can:
var potentialPosition = outerSphere.position + Random.insideUnitSphere * (radiusOuter - radiusInner);
To find a working position (one that does not intersect), the code can keep generating random positions until one is found that does not intersect.
To check if your position intersects with any 'planets', you can use:
Physics.CheckSphere(). It works well but it has a couple of drawbacks. First it checks the sphere against the bounding box of colliders (rather than the acutal mesh or collider). Second, if your outside sphere has a collider, you will have to do something in order for the check to find that object and always return true.
Physics.OverlapSphere() - this works like SphereCheck() except that it returns a list of collider. So you can examine the the list and weed out anything that should not impact the positioning.
Keep a list of 'planets' and compare the distance between them against sum of the radius of the planet and the target.
In my mind the last is the best approach. Note put a limit on the number of times your code tries to generate a good position (500 or 1000 for example). You don't want your code to hang if there is no good position.
Ah thanks I'll look into this now but I just have a question
What is radiusInner referring to?
Ok so I'm pretty puzzled, what will the radius of the Physics.OverlapSphere() be?
//I'm not sure I see how this will not just spawn the orbs outside //of the sphere when it gets smaller.
nm I think I know how to achieve what I need, I'll post back my code when it's finished
radiusInner will be the half of the localScale of the target. Take a look at this image:
The black line is the outer sphere. The turquoise circle is the inner/target sphere. The turquoise line is the radius of the target. The black line is the radius of the outer sphere. If you subtract the two, you get a radius that can only reach the red circle. Any positions within that circle will place the inner sphere within the outer sphere. That is what the one line of code does.