How to make a Crate Health C#
So im doing this for a school project. I have talked with three different professors now and they haven't been able to assist me in sorting this script out. It's due in a day so last resort is here. I have a damage volume attached to my projectile that should apply damage to the health system when it enters collider. All that works as i have a health system on my Avatar and works find. I can't copy paste that script onto the crate though, tried and it works but the way its setup to re-spawn the character it crashes the game because there is no re-spawn for the Crate. This is what i currently have.
using UnityEngine;
using System.Collections;
public class Crate : MonoBehaviour
{
public int maxHealth = 10;
public int currentHealth;
void Start ()
{
currentHealth = maxHealth;
}
public void ApplyDamage(int amount)
{
currentHealth -= amount;
if (currentHealth <= 0)
{
currentHealth = 0;
}
else
{
Destroy(gameObject);
}
}
}
Basically the Damage volume applies 10pts of damage per hit and i want the crate to be able to take 3 hits (30pts) of damage before being destroyed. I put the health in as a public int because eventually i wanted to make stronger crates so wanted to be able to adjust max HP easily from the inspector without having to do a separate script. Can anyone help me figure this out? Thank you in advance.
You didn't specify how your code wasn't working, but it looks like that if
statement isn't set up correctly. Try:
public void ApplyDamage(int amount)
{
currentHealth -= amount;
if (currentHealth <= 0)
{
currentHealth = 0;
Destroy(gameObject);
}
}
It's not working in that the Crate does not destroy. I have no way to tell if the Crate is taking any damage as it does not have a health bar or anything or that nature. That did not work unfortunately.
Answer by Amberite · Jun 06, 2018 at 09:57 PM
Interfaces to the rescue!
This might be a lot to take in at once and I'm not so great at explaining, but I'll do my best.
Interfaces are like a contract, they say "If this Interface label has been applied to a class, the class will 100% guaranteed use the methods described by the interface". This is super powerful (seriously, Interfaces are used everywhere). Here's how it works. First we define our Interface:
public interface IDamageable
{
void ApplyDamage(int damageAmount);
}
that can go in it's own IDamageable.cs script. Our contract is: "If the IDamageable label is on a class, it MUST have a method: public void ApplyDamage that takes this as a parameter: (int damageAmount)"
The method doesn't have any logic {}, because you put that in your class. Here's how that works, keep your Crate script and just change this:
public class Crate : MonoBehaviour : IDamageable
You may know that the class after our class name is what our class will inherit from (i.e. Crate inherits from MonoBehaviour), if we add another colon ':' we start telling the compiler which interfaces to apply (or in proper terms, implement). Remember, these stick on like labels, we can add as many as we like. Crate could implement a bunch of different interfaces. But for now we're happy with IDamageable.
Once you've done that, your IDE will check the Crate class to make sure it fulfils the IDamageable contract (Does it have a public method with the signature: public void ApplyDamage(int amount). It does, so you shouldn't get any errors.
So what did we gain from this?
Not much yet. I'm assuming you also have a method in your avatar class called ApplyDamage, with the same signature right? Go ahead and add the IDamageable interface to your avatar too. You might need to rejig your method name on your avatar to get this to work.
Here's where things get groovy: over in your projectile script, you probably have something like:
void OnCollisionEnter(Collision collision)
{
var avatarHit = collision.gameObject.GetComponent<GameAvatar>();
if (avatarHit != null) {
avatarHit.ApplyDamage(10);
}
}
Something like that? If you're looking for a GameAvatar class, that's all you ever find. But we can actually tell Unity to get the Interface instead of the actual class:
void OnCollisionEnter(Collision collision)
{
var damageable = collision.gameObject.GetComponent<IDamageable>();
if (damageable != null) {
damageable.ApplyDamage(10);
}
}
Now our projectile code doesn't care what it hits: if it has a component using the IDamageable interface, it will have its method called (passing in an int of 10 in my example.) This becomes super powerful because now our projectile code doesn't need updating every time we add something new to damage, and if we want to add a new damageable object to our game, we only need to make sure it has a component that implements IDamageable.
I hope all this helps, please let me know if not. Best of luck with your project.
Your answer

Follow this Question
Related Questions
Inherance script problem [C#] 0 Answers
Change Audio Mixer through script for every scene 0 Answers
Why Does this not work? please someone help me i am new to coding. 1 Answer
help to edit this script, zoom text ui 0 Answers
How to restrict rotation? 0 Answers