• entries
27
62
• views
25561

# Spawning, Item Drops, First Preview, Unexpected Fps Killer

923 views

Spent quite a bit of time tonight. Cleaned up a few things and got my enemy spawners and item drops working as well as a 'coin magnet'. Also, See below for a video of some gameplay.

For my item drops, I wanted to be able to assign a list of prefabs that the enemy could potentially drop in the inspector, as well as the % chance that the item would be dropped, and I wanted to do this so that the prefab name was right next to the % chance in the inspector.

The way I wound up doing this was created a DropItem class with the Serializable attribute, and simply gave it one each of public GameObject and float properties:using UnityEngine;[System.Serializable]public class DropItem { public GameObject dropItem; public float chance; }
That's the whole class.

Then, in my Enemy class, I created an array of DropItems and now my inspector looks pretty much how I wanted:

I realize that I could have customized the editor, but this works pretty well.

I've been thinking about what my different enemy types might drop, and it really seems like it will all be pretty much the same stuff I have already. I don't think I'm really going to implement any special items. I might throw a couple of larger money drops, but that's about it.

Also, you might notice there's only 1 pickup each for Ammo and Health. I'm going to make it so that the ammo pickup either adds to the ammo type for the currently equipped weapon (at time of drop), or to a random selection from the currently unlocked weapons. I haven't decided yet.

The health will be semi randomized between two values.

So that's great. Drops are working perfectly, except that Ammo and Health are just empty GameObjects with a Sprite on them at the moment. Won't be hard to finish them up though.

The other thing I managed tonight was to get my Spawner objects created. Each spawner takes a reference to a prefab that it will spawn, and has a min and max spawn time. After each enemy is spawned, the time until next spawn is set somewhere between those two points. These guys were easy, and are done as far as I'm concerned.

However, the whole wave-based play isn't done yet, and I'm going to ask for some thoughts on this. I've never implemented wave-based play before, so I'm not sure how to best approach it. The best idea I have so far is this:

I will create a SpawnerManager class which will have a reference to each spawner in the scene (I think that I can get away with a spawner on each side of the screen for each enemy type and just configure their random delays for play tuning) which will control the spawn speeds of each spawner, whether or not they're disabled (to enable/disable different enemy types for a given wave), and the number of enemies that should be spawned for the given wave.
.
For the first X waves, I will hard code the number of enemies in each wave as well as the time between waves (when the player will shop and upgrade). Also, I will manually enable or disable different spawners of different enemies on the first X waves, adding a progressive feel to the game. This will let me ensure a somewhat consistent experience for each user playing the 'main' part of the game. During these 'hard-coded' waves, I may also manually reduce spawn delays and time between waves as well, but more likely, I'll come up with some equation for a decent curve.

Because the game will have a number of weapons that can be bought and upgraded, as well as a number of skills and achievements, I want to give the player the opportunity to play potentially forever so that completionists can have their cake and eat it too. Not to mention that the game isn't beaten until the motorbike is repaired, which is a manual action by the player so they can choose to wait forever to repair it anyway.

In order to do this, after the first X waves, I'll use curves to automate the spawn numbers, delays and time between waves.

Does this seem like a decent approach?

Also, while I was testing my spawners my frames per second went from a steady 60 way down to 7. I knew something wasn't right, but I wasn't all that surprised with hundreds of enemies and projectiles on the screen.

I started commenting out some code, deleting game objects while the game was running, etc. to try and solve the problem. Turns out the problem wasn't with my spawners or enemies, but with my coin pickups. See if you can find the offending code: void Update() { rotateTemp.y += Time.deltaTime * spinSpeed; transform.eulerAngles = rotateTemp; AttractToMagnet(); } void AttractToMagnet() { float xDiff = Mathf.Abs(transform.position.x - stats.transform.position.x); float yDiff = Mathf.Abs(transform.position.y -stats.transform.position.y); if (xDiff <= stats.magnetStrength && yDiff <= stats.magnetStrength) { transform.position = Vector3.MoveTowards(transform.position, stats.transform.position, moveSpeed * Time.deltaTime); } print("hey"); }
**SPOILER SPACING**
*
*
*
*
*
*
*
*
*
*

At first glance, I thought, "Mathf.Abs() can't be that complicated... Maybe MoveTowards()?" Nope... it was print("hey"), which was just a test that the method was executing that I forgot to take out. Apparently, any more than 5 objects printing out every frame, and the framerate starts dropping like crazy, about 2 fps per object. Had a good laugh about this one.

Anyway, that's what I got done tonight. Check out this VIDEO with some descriptions of what's going on.

Yeah, Debug.Log and all the various text output is actually crazy slow in Unity.

Your magnet is going to be a square, not sure if that was your intention (or if it even matters).  You could probably do that with a trigger.  One trigger to determine if the coin should move towards the player, and then a collider or a second trigger to determine when the coin should be picked up.

Vid looks great, you're making quick progress.  I thought the circular bullet spray was an ability and not a bug at first =)

Yeah, Debug.Log and all the various text output is actually crazy slow in Unity.

Your magnet is going to be a square, not sure if that was your intention (or if it even matters).  You could probably do that with a trigger.  One trigger to determine if the coin should move towards the player, and then a collider or a second trigger to determine when the coin should be picked up.

Vid looks great, you're making quick progress.  I thought the circular bullet spray was an ability and not a bug at first =)

Yeah, it's not a bug, it's a 'feature' :p

And why is it that you're saying the magnet will be a square? Is that because I'm checking the x and yDiffs independently? It doesn't really matter, but I guess that checking their sum against my magnet strength would make the field circular?

And yeah, I could probably use a trigger and just scale it when my player upgrades their magnet strength, but I've been known to do things manually wherever I can (a folly sometimes, I know).

Since we're talking about triggers... I remember reading somewhere that OnTriggerEnter only works when something enters that GameObject's trigger who has the code attached, not if the GameObject who's checking for trigger collisions moves into another GameObject's space.

I think that's happening with my coins... When the player is still, the coins will move to his position, but the pickup action won't occur until he moves. Is this was you think is happening? I think I'm going to fix it just by checking the distance between the two, and trigger my Pickup() method then.