So I’ve written a script that scatters objects around the terrain for me and that part works great. But I want even better! I want it to look at the type of terrain (for simple testing I’m using ‘grass’, ‘dirt’, and ‘path’) and determine what kinds of scattered objects might appear, and then scatter a random assortment of those randomly across the map.
That was going well, I got the right list of ‘scatterables’ to the function that spawns them. But then I got lost trying to fetch the right prefabs. Here are the two scripts involved, both attached to the same singleton object in my game. The first one is a wrapper that lets me store the prefabs I’ll want to spawn in later. The second one is the spawner that should be scattering those objects.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AllObjects : MonoBehaviour {
// Here we store all possible objects, so we can attach them via the editor
public GameObject[] cubes;
public GameObject[] spheres;
public Dictionary <string, GameObject[]> items = new Dictionary <string, GameObject[]> ();
void Awake ()
{
items.Add ("cubes", cubes);
items.Add ("spheres", spheres);
}
}
using UnityEngine;
using System.Collections;
public class SpawnObjects : MonoBehaviour
{
public Terrain terrain; // add current terrain
public string[] objectToPlace; // list of objects to be placed on terrain
public GameObject placingObject; // the individual object we're currently placing
public int numberOfObjects; // number of how many objects will be created
public int posMin; // minimum y position
public int posMax; // maximum x position
public bool posMaxIsTerrainHeight; // the maximum height is the terrain height
public int numberOfPlacedObjects; // number of the plaed objects
private int terrainWidth; // terrain size x axis
private int terrainLength; // terrain size z axis
private int terrainPosX; // terrain position x axis
private int terrainPosZ; // terrain position z axis
private float yDisplace; // how far to move the object above the terrain
AllObjects items;
// Create objects on the terrain with random positions
public void PlaceObject()
{
items = GetComponent<AllObjects> ();
terrainWidth = 500; // get terrain size x
terrainLength = 500; // get terrain size z
terrainPosX = 0; // get terrain position x
terrainPosZ = 0; // get terrain position z
if(posMaxIsTerrainHeight == true)
{
posMax = (int)terrain.terrainData.size.y;
}
int posx = Random.Range(terrainPosX, terrainPosX + terrainWidth); // generate random x position
int posz = Random.Range(terrainPosZ, terrainPosZ + terrainLength); // generate random z position
float posy = Terrain.activeTerrain.SampleHeight(new Vector3(posx, 0, posz)); // get the terrain height at the random position
int r = Random.Range(0, objectToPlace.Length); // pick object type from scatterables list
int i = Random.Range (0, items [objectToPlace [r]].Length); // select prefab from list of items of that type
placingObject = items[objectToPlace[r]][i]); // set prefab as obj we're working with
if(posy <= posMax && posy >= posMin)
{
yDisplace = (placingObject.GetComponent<Renderer>().bounds.size.y)/2; // get height of object so it doesn't spawn half-buried
Instantiate(placingObject, new Vector3(posx, posy+yDisplace, posz), Quaternion.identity); // create object
numberOfPlacedObjects++;
}
// numberOfPlacedObjects is smaller than numberOfObjects
if(numberOfPlacedObjects < numberOfObjects)
{
PlaceObject(); // place another one
}
}
}
The issue is around lines 38-39 in the spawner. In this sccript, ‘objectsToPlace’ is a list of strings (it might be “cubes” or “cubes” and “spheres”). I want to randomly pick one of those object types (select “cubes”) in line 38, then randomly select from the possible prefabs of that type (items.cubes could have multiple cube prefabs, I want to pick one of them) in line 39. Line 38 works, I believe. But I’m having trouble referencing the right list in line 39. I think it might be looking for a list called “objectToPlace[r]” instead of a list called “cubes” or “spheres”.
Sorry if this isn’t super clear, I’ve only started learning unity and C# this weekend so I’m not positive I’m using the right terms for everything. But any pointers in the right direction here would be great thank you!