Forum begins after the advertisement:
[Part 5] Is there a better way to code Player damage?
Home › Forums › Video Game Tutorial Series › Creating a Rogue-like Shoot-em Up in Unity › [Part 5] Is there a better way to code Player damage?
- This topic has 1 reply, 1 voice, and was last updated 9 months, 2 weeks ago by Terence.
-
AuthorPosts
-
March 15, 2024 at 1:51 am #13560::
Luis Miguel Costa Perestrelo asks:
Hey, awesome tutorial!
Quick question as someone who is new to game dev: is it not a bit weird that the part of the code responsible for Damaging the player is in the EnemyStats script? I understand that it derives the damage value from there but it seems out of place.
Also, perhaps you talk about. This further in the tutorials, but in the case of multiple enemies, does vampire survivor still use i-frames? Or is it an independent damage “cooldown” for each enemy?
March 15, 2024 at 2:04 am #13561::In game dev, it is usually better for damage sources to handle it in their own scripts (contain the code for dealing damage) when they damage the player (or any other entity in the game for that matter, when we are dealing with more complex games).
In Vampire Survivors, this is not immediately obvious, because there aren’t multiple sources of damage for the player. But in other genres of games, where the player can get damaged by a variety of things, such as spikes or other environmental hazards, if we always let the player do the damage, things can get messy really quick. For example:
void OnCollisionStay2D(Collision2D col) { if (col.gameObject.CompareTag("Enemy")) { EnemyStats es = col.gameObject.GetComponent<EnemyStats>(); TakeDamage(es.currentDamage); } else if (col.gameObject.CompareTag("Spike")) { Spike s = col.gameObject.GetComponent<Spike>(); TakeDamage(es.damage); } else if (col.gameObject.CompareTag("Bomb")) { Bomb b = col.gameObject.GetComponent<Bomb>(); TakeDamage(es.areaDamage); } }
If you have many different categories of objects, this can lead the player script to become bloated really quickly, and it can make your code hard to read (enemy behaviours are all in one script, but the damage behaviour is somewhere else).
This is why, if you look at the source code for other games, you will find as well that if an entity is able to deal damage, it usually will get a reference to the other object it is dealing damage to and call the relevant damage function on that object. That way, all the behaviours and capabilities of that entity are contained in its own script.
Just as a bonus, I don’t really like using tags to check if an object is of a certain category. I prefer to do this:
void OnCollisionStay2D(Collision2D col) { EnemyStats es = col.gameObject.GetComponent<EnemyStats>(); if (es) // This will be false (i.e. fail) if the object does not have an enemyStats component. { TakeDamage(es.currentDamage); } }
That saves me the work of creating a new tag for every category of enemy, since I can just check for whether it has a certain component.
Regarding the invincibility frames, I’m not very sure of that (and I wasn’t able to find more information from a quick Google search as well). Let me know if you are able to find any more details on that! In Part 15, we recode the Garlic weapon and I cover how to track the damage cooldown for each enemy independently (in the earlier parts, our Garlic is not coded correctly).
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: