- Home /
Objects in object pool not reactivating.
I am setting up an object pool where characters(squirrels) are stored in a homeTree object. They then walk out onto a branch and are flung into gameplay one at a time. There are a total of 6 squirrels, so no more than 6 can be active at any time. As shown below, I have the squirrels activate at the homeExit, move to the launchPoint and wait to be launched. When a squirrel is launched, the next squirrel activates and moves to the launchPoint. After launching, they then move about the level until they make it back to the homeEntrance. When they reach the homeEntrance, they deactivate. If a squirrel touches the homeEntrance and there is no squirrel waiting at the launchPoint, it should appear at the homeExit and activate automatically.
I have two scripts, the SquirrelScript attached to the squirrelPrefab and the LaunchScript, which manages the object pool. My problem is that the squirrels deactivate, but do not reactivate once they make it back to the homeEntrance. And if one touches the homeEntrance before all of the other squirrels have launched, it prevents the other squirrels from activating as well.
Here is the code from the LaunchScript:
var numberOfSquirrelsToCreate : int = 0;
var squirrelLoaded : boolean;
var numberOfSquirrelsHome : int = 6;
function Start()
{
squirrels = new GameObject[numberOfSquirrelsToCreate];
InstantiateSquirrels();
SetSquirrel();
}
function InstantiateSquirrels()
{
for(i = 0; i < numberOfSquirrelsToCreate; i++)
{
squirrels[i] = Instantiate(Resources.Load("Prefabs/prefab_squirrel")) as GameObject;
squirrels[i].gameObject.SetActive(false);
}
}
//Called from the SquirrelScript when a squirrel is launched
function SetSquirrel()
{
if(!squirrelLoaded && numberOfSquirrelsHome > 0)
{
for(i = 0; i < numberOfSquirrelsToCreate; i++)
{
if(squirrels[i].active == false)
{
squirrels[i].SetActive(true);
squirrels[i].GetComponent(SquirrelScript).Activate();
numberOfSquirrelsHome--;
squirrelLoaded = true;
return;
}
}
}
}
//Called from the SquirrelScript when a squirrel is launched
function UnloadSquirrel()
{
squirrelLoaded = false;
}
//Called from the SquirrelScript when a squirrel reaches the homeEntrance
function LoadSquirrel()
{
numberOfSquirrelsHome++;
}
And here is the relevant code from the SquirrelScript:
function Activate()
{
yield WaitForSeconds(0.1);
transform.position = homeExit.transform.position;
preparingToLaunch = true; //Prevents another squirrel from loading before the first one has reached the launchPoint
squirrelActive = true; //Allows squirrel to move to launchPoint
isJumping = true; //Must be true in order to launch properly
squirrelDirection = true; //makes sure squirrel is moving to the right toward the launchPoint
}
function Deactivate()
{
gameObject.SetActive(false);
}
function OnMouseUp()
{
homeTree.SendMessage("UnloadSquirrel");
yield WaitForSeconds(1);
homeTree.SendMessage("SetSquirrel");
}
function OnTriggerEnter (theCollision : Collider)
{
if(theCollision.gameObject.tag == "homeEntrance")
{
Deactivate();
homeTree.SendMessage("LoadSquirrel");
homeTree.SendMessage("SetSquirrel");
}
}
Once you reactivate the gameObjects, have you tried manually calling their Start() routines?
That works, but unfortunately it instantiates the prefabs again causing six more to be added whenever the Start function is called.
You comments are a little hard to follow - I'm not sure I actually get when UnloadSquirrel is called. But it appears that squirrelLoaded is try after the first squirrel is launched - is that what you intended?
If start works, take whatever it is within it that makes it work and copy it to a new function. Then call that function ins$$anonymous$$d of Start()
whydoidoit:
Sorry, I know it's kind of confusing. The player clicks on the loaded squirrel, drags it back and releases to launch it (kind of like Angry Birds). UnloadSquirrel is called when the mouse button is released. It causes the next squirrel to activate and move the launchPoint.
Answer by SilentSin · Oct 22, 2013 at 03:50 AM
I believe I know what your problem is.
What's happening appears to be: -> Squirrel is fired -> Gets back to the home entrance -> Disabled -> When needed again, enabled and placed at the home exit.
The problem appears to be that you are enabling the squirrel while it is still at the home entrance, which I believe would call OnTriggerEnter immediately, which deactivates it again immediately.
So all you need to do is reverse the order of these two lines:
squirrels[i].SetActive(true);
squirrels[i].GetComponent(SquirrelScript).Activate();
So you move the squirrel then activate it.
Thank you! Swapping those lines of code didn't work (when I tried that it gave me an error saying that the prefab was inactive). But you were right about the core reason it wasn't working. It was beco$$anonymous$$g active again while still inside the homeEntrance trigger, which caused it to become inactive again immediately. So I just set the function to be called when exiting the homeEntrance and it worked perfectly. Thanks again!
Yeah, the yield WaitForSeconds(0.1); can't work on an inactive object, sorry.
If you do want to have it triggered by OnTriggerEnter:
put transform.position = homeExit.transform.position; before the yield. add SetActive(true); between that line and the yield remove squirrels[i].SetActive(true); from SetSquirrel()
That way, the Activate() function takes care of everything the squirrel does to activate itself.