Developing a final boss battle: Cycling through destructable sections.
Let’s recap on some things I’ve shared and a few I haven’t. First of all, there’s a set of waypoints I’ve called Paths (0) through (9) placed in their own empty holder.
Inside of the boss, there was an empty named “bossMover” that was put there to compare with the path waypoints, but we don’t need it, The boss’s own Empty is the rightful king of the transform and will be used to match the path waypoints. We’ll just put the boss graphic behind it.
Inside of the boss, I’ve placed other empties called sections that match the path. The idea is that when all of the items inside of that section are destroyed, then that point of the path is deleted and we cycle through the remaining paths. (Little did I know this was easier said than done).
BossSection.cs:
I also put a script on the section called BossSection.cs. Its only job is to look out that there are no more objects inside of it and let the boss script know it's empty; This is done with the transform.childCount command. Just check if it’s 0 and we’re good to go!
Editing lists can only be done by the originating class it seems.
For whatever reason, I had a lot of problems working with the List array. While it would accept pruning at the boss level, if the child script would ask for it, it would throw an out-of-range error, even if the child script ran the method inside of the parent. If anyone knows why this happens, and how to get around it, I’d appreciate the info.
Event — part 1:
I got around this by creating an event where the section would announce its empty and give its identification. These are the first two lines of the code, setting up the event.
public delegate void DeleteSection(int sectionID);
public static event DeleteSection deleteSection;
Make sure the announcement is done only once:
Each section is given an id in Unitys inspector and we set up a boolean so we only make the announcement once. Before, the script would constantly be announcing the event but once the boolean gets switched, then it sends the event no more! (A very grateful thank you Paul Marsh for seeing this. I was befuddled for days wondering why 1 bullet from the ship was taking out several sections!)
So once we check to see if the message has been sent, if it hasn’t, we’ll now announce the ‘deleteSection’ event and give the id as the parameter so the boss will know which section to delete from the path.
Boss.cs:
Event — part 2:
This is the other half of the event, we now assign the IgnoreSectionNow function to the deleteSection in the Section script.
void OnEnable(){ BossSection.deleteSection += IgnoreSectionNow; }
void OnDisable(){ BossSection.deleteSection -= IgnoreSectionNow; }
So the event is announced, the id is passed in it. Here we’re getting the id, and we’re going to use it to piece together the name of the path that I have in the inspector. Let’s say we destroy section 1. x will become “Path (1)”, the name of the actual gameObject we want to delete.
How to properly prune Lists:
Here’s the important part. If you’re cycling through a List, you just can’t use Remove or RemoveAt because things will shift and throw everything off. There are several options, but going through the List one by one backward using a for loop and *then* using RemoveAt is a safe way to do what we want.
so while we’re going through each item, we’re going to compare the name we pieced together with the name of the game object inside of the list array at variable i. Also, note that we had to use “.transform.name”. Anything else and it’s a mismatch between a string and a gameObject; we need the name and fortunately it’s available to us through the transform!
So once we do discover a match between the string and gameObject name, we use the RemoveAt(i) (you delete it where you found it) and then immediately choose a new waypoint for the rest of the program to keep moving.
Once we’ve found our matching path, there’s no reason to keep going through the loop so we break out of it.
The rest of the code is mostly unchanged from yesterday though I put movement in a coroutine to take advantage of the yield returns that can help give pauses to movement and I also put a check to stop movement when there’s only 1 section left.
So let’s see it in action! I’ll let it cycle through the entire ship once before I start destroying sections.