How to destroy an prefab Object after the second hit?
Hello
I started two weeks ago with Unity and a book what gives me some examples. I created a typical Breakout game and building my second level now. I use a prefab for the brick. Now i want to put in bricks ,that can just be destroyed after the second hit. So i created a second prefab "HarderBrick". I tried for days now. I put the normal bricks and the harder bricks in with their own for_loop and clone them with Instantiate( prefab,position,Quaternion.identity).
In the collisionEnter2D i use a hitcounter.
if(collision.tag=="HarderBrick") { hitcount++; play sound ;
if(hitcount ==2) { destroy brick points++ } } That works partially, first time i hit a "Harderbrick "it stays, but if the ball hits another "HarderBrick" it gets destroyed.
So how can i make sure the same brick gets destroyed after two hits and not another one?
I already tried to save every instantiated prefab ID in an array with getInstanceID and work with that. But i am not sure i am on the right track here.
Tried to compare the InstanceID with each other but it did not work.
If anyone knows an better way i am thankful for sharing with me.
Answer by joepeijkemans · Jun 04, 2020 at 09:33 AM
The problem is probably that you have the variable hitcount as public. This means that all bricks share the same variable hitcount, and if hitcount == 2, all harderbricks are destroyed.
I suggest, first of all, making this variable private, since the hitcount is unique per brick. And secondly, to simply create a class "Brick", with a few parameters, Including one saying how many hits they can take. That'd be easier than just having to make an unique prefab for every amount of hits a brick can take, whilst they still function the same.
Hello joepeijkemans
Thats a good idea, ill try that.Thank you! I will come back here if i fail :D
The problem is probably that you have the variable hitcount as public. This means that all bricks share the same variable hitcount
The access modifier has nothing to do with the fact that all instances share the same value. The static
modifier does.
Answer by Hellium · Jun 04, 2020 at 12:14 PM
According to your conditions, your code is on a script attached to your ball, right?
I believe it should be the opposite, meaning the code should be on the brick.
public class Brick : MonoBehaviour
{
[Min(1)]
public int TotalHitCountBeforeDestroy = 1;
private int remainingHitCountBeforeDestroy;
private void Awake()
{
remainingHitCountBeforeDestroy = TotalHitCountBeforeDestroy;
}
void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.CompareTag("Ball"))
{
remainingHitCountBeforeDestroy--;
if(remainingHitCountBeforeDestroy == 0)
Destroy(gameObject);
}
}
}
If you attach the script on your brick, you will be able to set the TotalHitCountBeforeDestroy
, create as many different prefabs you want of your bricks with different values and aspect.
If you want to be warned when a brick is destroyed, you can take advantage of events.
public class Brick : MonoBehaviour
{
[Min(1)]
public int TotalHitCountBeforeDestroy = 1;
private int remainingHitCountBeforeDestroy;
public event Action Destroyed;
private void Awake()
{
remainingHitCountBeforeDestroy = TotalHitCountBeforeDestroy;
}
void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.CompareTag("Ball"))
{
remainingHitCountBeforeDestroy--;
if(remainingHitCountBeforeDestroy == 0)
{
Destroyed?.Invoke();
Destroy(gameObject);
}
}
}
}
Then, in your spawner script:
public class BrickSpawner : MonoBehaviour
{
public Brick[] BrickPrefabs
// ScoreManager is a custom class you will need to make to handle the score. See below for an example. Then drag& drop it in the inspector
public ScoreManager ScoreManager;
public event Action Destroyed;
private void Start()
{
SpawnBricks();
}
void SpawnBricks()
{
for( .... )
{
SpawnRandomBrick();
}
}
void SpawnRandomBrick()
{
Brick brick = ....
brick.Destroyed += () => ScoreManager.Score++;
}
}
public class ScoreManager : MonoBehaviour
{
private int score;
// Drag & drop text
public UnityEngine.UI.Text ScoreText;
public int Score
{
get => score;
set
{
score = value;
ScoreText = score.ToString();
}
}
}
Hello Hellium
Yeah you are right, it is attached to the Ball. And i see, ins$$anonymous$$d of checking the ball of hitting a brick, i check the bricks of getting hit by the ball. That makes sense. Thank you ill try that. I don´t have a Score$$anonymous$$anager yet, i just increment points and let is show in a canvas->UI->Text.
Your answer
Follow this Question
Related Questions
Can't make the player attack an enemy 0 Answers
Collisions not working in top-down RPG? 0 Answers
Changing material dose not change the appearance of the game object 0 Answers
how do i collide and kill the enemy while pressing space Unity 5 C# 2 Answers
Collision Detection between two different Prefabs doesnt work 1 Answer