- Home /
Keep constant number of prefabs
This should be fairly trivial and I don't know what's wrong with my script. I seem to have trouble understanding how to send messages.My gamemanager script keeps track of the number of prefabs and has two functions that are called when a prefab is created/destroyed. I checked that both CountPlatformsUp() and CountPlatformsDown() are called, but my "platforms" variable doesn't keep track and once destroyed platforms are not spawned in Update().
Why?
From the prefab:
function Start () {
gameManagerObject.GetComponent(_gameManagerScript).CountPlatformsUp();
}
function OnDisable() {
gameManagerObject.GetComponent(_gameManagerScript).CountPlatformsDown();
}
The gamemanager:
var platformPrefab : GameObject;
var spawnAreaObject : GameObject;
private var spawnAreaTransform;
private var platforms : int = 0;
function Start () {
spawnAreaTransform = spawnAreaObject.GetComponent(Transform);
}
function Update () {
if (platforms <= 20) {
SpawnPlatform();
}
}
function CountPlatformsUp () {
platforms = platforms + 1;
}
function CountPlatformsDown () {
platforms = platforms - 1;
}
function SpawnPlatform() {
var targetPos : Vector3 = Vector3(Random.value * spawnAreaTransform.position.x, Random.value * spawnAreaTransform.position.y, 1.434096);
Instantiate(platformPrefab, targetPos, Quaternion.identity);
//platforms = platforms + 1;
}
aldonaletto already gives you a better solution for your problem, but your original way have some problems:
If you use OnDisable, you should use OnEnable as counterpart.
it seems your platform script have a public variable called "game$$anonymous$$anagerObject" . Do you assign the gamemanager object somewhere? Esp. for new created platforms? Note that you can't assign objects from the scene to variables of prefabs.
The game$$anonymous$$anagerObject variable should be of type "_game$$anonymous$$anagerScript" so you avoid the GetComponent calls.
A better way would be to make the Game$$anonymous$$anager a singleton by holding a public static reference to the manager object.
In the "_game$$anonymous$$anagerScript.js" script:
static var instance : _game$$anonymous$$anagerScript;
function Awake()
{
instance = this;
}
In your platform script:
function OnEnable () {
_game$$anonymous$$anagerScript.instance.CountPlatformsUp();
}
function OnDisable () {
_game$$anonymous$$anagerScript.instance.CountPlatformsDown();
}
$$anonymous$$any thanks for the suggestions. To my defense - I am coding a quick prototype, thus the messy coding. Should have mentioned it. I'd like to understand why the "if (platforms <= 20)" does not get called in Update(). Any ideas?
I was using OnDisable because Unity lacks OnDestroy(). But you are right, OnEnable would be better especially if I were to reuse objects ins$$anonymous$$d of instantiating new ones.
Both the gamemanager and the platforms are prefabs and I assigned a reference from the gamemanager to the platform prefab.
You are right, thanks.
Good idea with the singleton. I am aware of the pattern but still new to Unity.
Answer by aldonaletto · Jan 21, 2012 at 02:37 AM
Is the game manager script called "_gamemanagerScript.js"? You should pass the script name without quotes or extension to GetComponent - if the name is "GameManagerScript.js", use GetComponent(GetManagerScript).
Anyway, there's a good method to keep track of the current population of platforms: create an empty object, call it "Platforms", reset its position and rotation and assign the script below to it. Whenever a new platform is created, it's childed to the Platforms object - this way you can just check childCount to know how many platforms are alive (Unity always updates the childCount when a child is added or destroyed).
var platformPrefab : GameObject; var spawnAreaObject : GameObject;
private var spawnAreaTransform;
function Start () { spawnAreaTransform = spawnAreaObject.transform; // get transform directly }
function Update () { if (transform.childCount
function SpawnPlatform() { var targetPos : Vector3 = Vector3(Random.value spawnAreaTransform.position.x, Random.value spawnAreaTransform.position.y, 1.434096); var platf: GameObject = Instantiate(platformPrefab, targetPos, Quaternion.identity); platf.transform.parent = transform; // child the new platform to this object }
Very cool. Thanks. Will do that. I wonder though why my initial and messy script wasn't working correctly.