Hey guys,
My game has boulders that fall from the top of the screen and you click on them to destroy them, my only problem is that with the code I have, when you click on 1 boulder, it will destroy all the boulders currently on the screen.
My boulders also have a trail visual effect that makes it look like its in motion, so for this I copied the sprites and layered them on and changed the transparency accordingly, if I didn’t change the code the way I did only the main boulder would get deleted, and the ‘trail’ effect sprites would still linger
if (Input.GetMouseButtonDown(0))
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
{
var boulder = gameObject;
if (boulder == null)
{
return;
}
foreach (Transform child in transform)
{
GameObject.Destroy(child.gameObject);
Debug.Log(child);
}
speed = 1;
ScoreValue.scoreValue += 1;
breakSource.Play();
Destroy(hit.collider.GetComponent<BoxCollider>());
Destroy(boulder.gameObject, 0.4f);
}
}
I’d like to keep the functionality the same, but could anyone give me some pointers as to how I can get the on click to stop destroying every boulder thats on the screen? thanks a ton.
edit: Also I don’t destroy the boulder right away on click, I slow its speed and let it linger for a moment to let the animation play
What is the loop starting on line 16 above destroying? It appears to be destroying all children of the GameObject that this script is located on… is that your problem? What happens if you remove the line 18 destroy?
Good spotting above there @Olmi … I didn’t notice that.
Setting boulder = gameObject implies that this script is ON the boulder.
However, the raycast hit value is being used to destroy a box collider, and the boulder is used for the delayed destroy. This also implies that every time you click, EVERY boulder is raycasting into the scene…
This is an unusual pattern: usually you have a single script instance (think of it as a weapon) that raycasts into the scene to see what you hit, and then destroys the things that it raycast-hits. Those things might have a function you could call so they know how to destroy themselves, ie. delaying, animating, particles, to keep your “areas of concern” centralized into the objects you’re blowing up, which might be boulders now, but in the future could be ships, which might take multiple hits and have health, for instance.
I’m a fairly inexperienced coder so I apologize. The script is on the boulder, and the foreach loop is used to delete the “trail” images on the boulder (it looks weird if the motion trail is still there when the break animation is playing).
An additional problem is that you can keep clicking on the boulder while its in break animation to keep gaining points, and also destroy more boulders coming into the scene. when i say the trail images, i mean the 2 transparent boulders above it, thats what the foreach is meant to destroy, these are just 2 game objects with sprite renderers Imgur: The magic of the Internet
You have this script running on every single boulder, and never check which boulder was hit by the raycast.
And because the script evaluates true that some boulder was hit, they are all destrotyed.
Move your raycasting logic to a single manager object.
To stop gaining points during the breaking animation, you destroy the collider on the hit object so it can’t be clicked again (you already doing this, just fix the other problem first)