- Home /
Looking for help with differentiating collisions between game objects.
I'm making a 2.5d platformer that has a dude casting different spells.
My question is this: What should I look into to be able to differentiate spells on collision. Currently, I have the know-how to make it so that when there's a collision objects a, b or both are destroyed. That's a little too simple, and I'd like to have effects based on whether or not "fire" or "water" has hit something. The goal here is that I'm not just doing "damage", I'm applying effects.
I'm not looking for code, per se, since I haven't provided any. I'm fully willing to do the research and read into it, but I'm not even sure where to start. I haven't had any luck googling it so I'm forced to assume I'm not even sure what it's called.
Thank you in advance for any bones thrown my way!
Answer by Bampf · Sep 28, 2010 at 12:51 PM
When a spell is cast, you will most likely create a GameObject that represents the spell's area of effect. This object can move, will probably have a collider, as well as one or more visual components (particles, mesh, etc.) Maybe the audio for the spell will also be on it- you'll hear the sound position change in 3D that way.
You'll probably set up one or more spell objects in this way and store them as prefabs, to be instantiated later whenever a spell is cast.
You'll also most likely have your own script(s) attached to this GameObject. These scripts will make it fly across the scene, shrink or grow over time, play sounds, etc.
Given this setup, here are two ways to do what you want.
1) Let's say you have a script called Spell that you've dragged onto this GameObject. Any public variables of Spell will appear in the inspector. So you could have a variable "spellType" that represents what type of spell it is. Or, "fireDamage", "waterDamage" could be integers of how much of each type of damage is done.
If the Spell code is what detects the collision, which I think is a good way to do it, then Spell could SendMessage to the objects it collides with. Those objects, if damageable, would respond to the message, adjusting their hit points and so on.
2) If you spells are fairly similar in appearance and behavior, then method 1 may be good enough. Otherwise, it's a good starting point and we can take it to the next level. Instead of one general purpose Spell class with variables that control the effects, you could make vastly different scripts and gameobjects. Maybe one spell is more like a projectile, another is a wall, and a third is a sleep spell, for example. Each would have its own class (FireSpell, WallSpell, etc.) and they could do vastly different things. One might stay put, another might not be visible at all, but instead would cause an enemy to move slowly for a while.
So to summarize, spell scripts send messages to things the spell hits, and the enemy scripts can respond or not, depending on what type of damage they take, whether they get sleepy, etc.
Answer by FreeTimeDev · Sep 29, 2010 at 09:34 AM
@Bampf
You've answered everything beautifully, but one thing:
How am I to (best) detect whether or not my fireball has (for instance) hit my Wall spell?
Fortunately, my set up wasn't too far off from what you have suggested. I have an empty gameobject to use to spit out Spells (eventually, to set in my model's hands). This game object has fireBall and earthWall scripts on it. On the Earthwall prefab I have another script to handle other things (time to live) and I think this is where my new function should sit.
Here's what I have so far:
//Fireball spell:
var damage : int = 100;
function OnCollisionEnter(collision : Collision) { SendMessage("FireBall", damage); }
//Wall spell:
function FireBall(damage : int) {
print ("earth wall was hit by a fireball for "+damage+"!");
}
There are no errors, and no printing.
After more work, I've discovered that the following works:
if (collision.gameObject == gameObject.Find("FireBall(Clone)")) { print("FB hit EW");}
This is applied to a script on the wall, which is constantly detecting collisions. Seems a bit obtuse.
This seems sloppy to me. Are there any improvements upon this?
I ran into this once. When you instantiate the prefab it assigns a unique name by adding "clone", which makes it hard to search for. I believe my solution was to never Find by name. What you want to do is get your collider working, and in OnCollisionEnter (or OnTriggerEnter if you are using triggers) you know both objects that are colliding. Then you either send messages, or in a pinch you can call GetComponent to see if one is a Fireball or whatever.
So finish the thought, you could change your code to: if (collision.GetComponent(Fireball) != null) { .. }. What gives me pause is that you might end up hardwiring wall-to-fireball logic into the wall code. Depending on what spell interactions are possible, you may want that logic on the fireball ins$$anonymous$$d, or maybe you'll want a central spell handler that manages all spell-spell and spell-human interactions. Let's treat that as a separate topic. :-)