I was trying to re-enable my sprite renders after a certain amount of time after being “eaten” by the player. Because, after the objects return to our pool and re-spawn they are still disabled. Looking like they were already “eaten”.The weird thing is that I was calling GetComponent(); in on trigger enter and that was working fine. But, when I try to write a new void (that would be called after the on trigger enter) to enable and turn back on the sprites. Unity won’t autocorrect and said that it didn’t contain a definition for enabled? How can we fix this? any workarounds?
//Called when the player enters a triggerer zone
public void OnTriggerEnter2D(Collider2D other)
{
//If the submarine is collided with a coin
if (other.tag == "Coin")
{
//Notify the level manager, and disable the coin's renderer and collider
levelManager.CoinCollected(other.transform.position);
other.GetComponent<Renderer>().enabled = false;
other.GetComponent<Collider2D>().enabled = false;
AudioManager.Instance.PlayCoinCollected();
Invoke("SquishyReappear",7);
}
//If the submarine is collided with an obstacle
else if (other.tag == "Obstacle")
{
//Notify the level manager, and disable the obstacle's renderer and collider
levelManager.Collision(other.name, other.transform.position);
//other.GetComponent<Renderer>().enabled = false;
other.GetComponent<Collider2D>().enabled = false;
GetComponent<Animator> ().Play ("TurtleCrash");
AudioManager.Instance.PlayExplosion();
//If the obstacle is a torpedo, disable it's child as well
if (other.name == "Torpedo")
other.transform.FindChild("TorpedoFire").gameObject.SetActive(false);
if (other.name == "FrontShark")
GetComponent<Animator> ().Play ("TurtleCrash");
//If the player is vulnerable
if (playerVulnerability == PlayerVulnerability.Enabled)
{
//Sink the submarine
powerupUsage = PowerupUsage.Disabled;
playerVulnerability = PlayerVulnerability.Disabled;
playerStatus = PlayerStatus.Sinking;
GetComponent<Animator> ().Play ("TurtleCrash");
//BackgroundStop.enabled =false;
BackgroundStop.speed = 0.0f;
//Waterline.enabled = false;
Waterline.speed = 0.0f;
Waterline2.speed = 0.0f;
Turtle.isKinematic = true;
normalCollider.enabled = false;
GetComponent<BoxCollider2D>().enabled = false;
//Debug.Log ("Turtle is now Kinematic");
TurtleBackgroundOffset2.enabled = false;
IsDead = true;
//Debug.Log("player is dead");
subRenderer.sprite = subTextures[currentSkinID * 2];
bubbles.Stop();
}
//If the player is shielded, collapse it
else if (playerVulnerability == PlayerVulnerability.Shielded)
{
CollapseShield();
}
}
//If the submarine is collided with a powerup
else if (other.tag == "Powerup")
{
//Notify the level manager, and disable the powerup's components
other.GetComponent<Renderer>().enabled = false;
other.GetComponent<Collider2D>().enabled = false;
other.transform.FindChild("Trail").gameObject.SetActive(false);
AudioManager.Instance.PlayPowerupCollected();
levelManager.PowerupPickup(other.name);
}
}
public void SquishyReappear()
{
Squishy = GameObject.FindGameObjectsWithTag ("Coin");
Squishy.GetComponents<Renderer>().enabled = true;
Squishy.GetComponents<Collider2D>().enabled = true;
}
You’re using ‘GetComponents’, the plural version. You get an array and forgot to access a specific element.
Either loop through them if you have several components of the type on the objects, or directly access one using an index ( [0] for example). Or, if you’re sure you’ll only have one of those components each, just use GetComponent which returns a single component.
Ok I got the array to work, but I used set active instead of GetComponent. I figured that should reset all the comments on the game objects.
However now, there is a new problem. Since many objects share the tag “coins” it is resetting all the objects tagged as so, on and off together. Including the objects that have just spawned and are still onscreen.
Updated Code:
//Called when the player enters a triggerer zone
public void OnTriggerEnter2D(Collider2D other)
{
//If the submarine is collided with a coin
if (other.tag == "Coin")
{
//Notify the level manager, and disable the coin's renderer and collider
levelManager.CoinCollected(other.transform.position);
other.GetComponent<Renderer>().enabled = false;
other.GetComponent<Collider2D>().enabled = false;
Invoke("SquishyReappear",20.0f);
//other.GetComponent<Renderer>().enabled = true;
//other.GetComponent<Collider2D>().enabled = true;
AudioManager.Instance.PlayCoinCollected();
}
public void SquishyReappear()
{
StartCoroutine(SquishyReappearNow());
}
IEnumerator SquishyReappearNow ()
{
Squishy = GameObject.FindGameObjectsWithTag ("Coin");
foreach (GameObject _obj in Squishy)
{
_obj.SetActive(false);
Debug.Log("Squishies is set to false");
}
yield return new WaitForSeconds (5.0f);
Squishy = GameObject.FindGameObjectsWithTag ("Coin");
foreach (GameObject _obj in Squishy)
{
_obj.SetActive(true);
Debug.Log("Squishies is set to true");
}
Hope, you can help, and thanks for the continued support.
Skip the invoke and start coroutine directly. Put the delay in the coroutine. pass the coin as an argument to the routine and use this reference instead of finding all objects tagged coin. you could also offload this logic to a component on the coin itself.