Randomly placing items script not working - sometimes items spawn in walls, sometimes items spawn in weird locations

Posted by Timothy Williams on Game Development See other posts from Game Development or by Timothy Williams
Published on 2012-09-05T18:31:37Z Indexed on 2012/09/05 21:51 UTC
Read the original article Hit count: 330

Filed under:
|
|

I'm trying to figure out a way to randomly spawn items throughout my level, however I need to make sure they won't spawn inside another object (walls, etc.)

Here's the code I'm currently using, it's based on the Physics.CheckSphere(); function. This runs OnLevelWasLoaded(); It spawns the items perfectly fine, but sometimes items spawn partway in walls. And sometimes items will spawn outside of the SpawnBox range (no clue why it does that.)

//This is what randomly generates all the items.
void SpawnItems () {
    if (Application.loadedLevelName == "Menu" || Application.loadedLevelName == "End Demo")
        return;

    //The bottom corner of the box we want to spawn items in.
    Vector3 spawnBoxBot = Vector3.zero;
    //Top corner.
    Vector3 spawnBoxTop = Vector3.zero;

    //If we're in the dungeon, set the box to the dungeon box and tell the items we want to spawn.
    if (Application.loadedLevelName == "dungeonScene") {
        spawnBoxBot = new Vector3 (8.857f, 0, 9.06f);
        spawnBoxTop = new Vector3 (-27.98f, 2.4f, -15);
        itemSpawn = dungeonSpawn;
    }

    //Spawn all the items.
    for (i = 0; i != itemSpawn.Length; i ++) {
        spawnedItem = null;
        //Zeroes out our random location
        Vector3 randomLocation = Vector3.zero;
        //Gets the meshfilter of the item we'll be spawning
        MeshFilter mf = itemSpawn[i].GetComponent<MeshFilter>();
        //Gets it's bounds (see how big it is)
        Bounds bounds = mf.sharedMesh.bounds;
        //Get it's radius
        float maxRadius = new Vector3 (bounds.extents.x + 10f, bounds.extents.y + 10f, bounds.extents.z + 10f).magnitude * 5f;
        //Set which layer is the no walls layer
        var NoWallsLayer =  1 << LayerMask.NameToLayer("NoWallsLayer");
        //Use that layer as your layermask.
        LayerMask layerMask = ~(1 << NoWallsLayer);

        //If we're in the dungeon, certain items need to spawn on certain halves.
        if (Application.loadedLevelName == "dungeonScene") {
            if (itemSpawn[i].name == "key2" || itemSpawn[i].name == "teddyBearLW" || itemSpawn[i].name == "teddyBearLW_Admiration" || itemSpawn[i].name == "radio") 
                randomLocation = new Vector3(Random.Range(spawnBoxBot.x, -26.96f), Random.Range(spawnBoxBot.y, spawnBoxTop.y), Random.Range(spawnBoxBot.z, -2.141f));
            else 
                randomLocation = new Vector3(Random.Range(spawnBoxBot.x, spawnBoxTop.x), Random.Range(spawnBoxBot.y, spawnBoxTop.y), Random.Range(-2.374f, spawnBoxTop.z));                 
        }
        //Otherwise just spawn them in the box.
        else 
            randomLocation = new Vector3(Random.Range(spawnBoxBot.x, spawnBoxTop.x), Random.Range(spawnBoxBot.y, spawnBoxTop.y), Random.Range(spawnBoxBot.z, spawnBoxTop.z));   

        //This is what actually spawns the item. It checks to see if the spot where we want to instantiate it is clear, and if so it instatiates it. Otherwise we have to repeat the whole process again.
        if (Physics.CheckSphere(randomLocation, maxRadius, layerMask))
            spawnedItem = Instantiate(itemSpawn[i], randomLocation, Random.rotation);
        else
            i --;

        //If we spawned something, set it's name to what it's supposed to be. Removes the (clone) addon.
        if (spawnedItem != null)
            spawnedItem.name = itemSpawn[i].name;
    }
}

What I'm asking for is if you know what's going wrong with this code that it would spawn stuff in walls. Or, if you could provide me with links/code/ideas of a better way to check if an item will spawn in a wall (some other function than Physics.CheckSphere).

I've been working on this for a long time, and nothing I try seems to work. Any help is appreciated.

© Game Development or respective owner

Related posts about c#

Related posts about unity