Monday, November 18, 2013

Shots and Particles

Greetings everyone, I am Khoa.  Like Kyle, I am not actually enrolled in the class and am more of contract worker.  My role so far is to program the various shots and bullets used by both player and enemies.

Information: From and To Where
So imagine shooting a bullet and said bullet hitting an enemy and said enemy takes damage.  Simple, no?  To make it more complex, imagine two more bullet types, one which will hurt the enemy more, and one that will make the enemy more aggressive but will not deal any damage.  Now imagine multiple enemy types which will be affected differently depending on the bullet type.

There are two ways of approaching this issue:
- Have each bullet check which enemy/object it struck.
- Have each enemy/object check which bullet type struck it.

Both are equally valid and depends on how the coding structure have been set up as well as how many of each type there are.

For Bala, we decided for each bullet to pass relevant information to the enemy/object it struck.  There are several reasons for this, two of which are:

- The main bullet controller, from which specific bullets will be derived from, had been set up to pass information to the enemy/object
- The development is progressing to a point where it seems there will be more enemy/object types than bullet types

The first reason is fairly obvious.  If the bullets can already pass information downstream to the objects, why not pass the type of bullet down as well, instead of having the bullet figure out what it just hit.

The second reason lightens the amount of script that has to be generated and lightens the amount that has to be processed.  There will be more bullets than enemies, especially including the player's own bullets, that if every bullet has to do needless calculations, performance will needlessly suffer.  Supposing there were four types of bullets and twenty types of enemies.  An enemy controller script going through four types of bullets is much faster than a bullet controller script going through twenty types of enemies.

Here is a small map of how each bullet type is extended from the main controller.


Simple, and each type is responsible for turning on their particles.  We have also been planning on allowing the player to upgrade their bullets, so extending their methods would be easier and cleaner.

Here is an example of the water shot checking what it hit.


So if we add more enemies, we would have to update this script repeatedly.

Instead, here is what it should look like.


And in the enemy script, such as the Fire Demon:


This allows for the Fire Demon to check just which type of bullet struck it and react accordingly.
We cut down on the amount of information that has to be re-written and checked.

So Bullets?
As noted in an earlier post, the player will get different types of bullets with different abilities:
- Knife: Standard damaging bullet
- Water: Good versus fire type enemies/fill holes/destroy some obstacles
- Wind: Push objects and enemies around/not damaging
- Shield: Blocks and reflects enemy shots

Since the knife is the standard shot, we'll take a look at it first.


The knife simply flies forward and if it hits an object that can take damage, it will pass how much damage to the object.  The damage calculation is determined by the object and so if an object is immune to the knife, it can be set to ignore the damage from the knife.  This keeps us from having to add more to the knife every time we create a new enemy type.

Water is a bit more interesting as it can be used to shrink down sugar cubes, deal damage to certain enemy types and raise water levels.



The particles themselves is not causing the cube to shrink, nor do they carry any of the logic that determines what happens when it collides with another object.  Like the knives, the actual shots are these spheres, the difference is that the spheres are not rendered.


They pass the "damage" and other relevant information to the objects which then processes what has to happen.

Now, why can't the particles themselves be used?  In a sense they can.  Unity particles can collide and pass messages based on those collisions.  In fact, an early example of the wind shot did just that.


In this early wind shot prototype, I wanted to see if I can replicate the wind bouncing off of walls and how the particles would flow.  However, I was not able to get very precise control of the particles.  By nature, wind moves randomly and so the particles did exactly what I told them to do.  Likewise, the wind is not only affected by the environment, but also by itself.  The movement of the particles is a bit more natural, but would be frustrating for a player to utilize.

Instead, we went back to the more streamlined shots we had before.  The wind shot works in almost exactly the same way as the water shot.




Now if you notice, while the spheres are being instantiated just like the knives, the particles themselves extend forward from the player.  This is done by toggling the particle systems on and off which spray the particles forward in the direction the player is currently looking and not by instantiating the particle systems.

This is the other reason not to use the particles themselves for calculations.  To get the spiraling wind, I overlay two sets of particles, each set containing four streams.  That said, none of them are going to hit anything in the center of the cone, which realistically makes sense since it would be the eye of the storm, but in game would seem awkward since that would be where the force would be expected to be strongest.  No to mention, to create the streams, I use more particles which means more collisions, more processing that needs to be calculated, and it would be a nightmare for everyone involved to determine how many collisions are needed to kill a single enemy.

And now for something, somewhat different.  The shield is not a bullet in the same sense that the others are.  It instead blocks shots and repels them.  It will always face the same direction as the player is facing.  Like the cone of wind, it always exists and does not need to be instantiated every time.


That's all for now, folks.  This quarter is coming to a close and afterwords will be a postmortem on whether or not we achieved our targets.  It will also address what's going to happen next and where Bala is heading.  Until then.

No comments:

Post a Comment