Tried searching for something related but just found answers of 2-7 years ago about this saying to not use interfaces but then I discovered that they implemented the support for interface in Unity 5 , but when I tried following the tutorial from Code Monkey about interface and use it on my game it still can't find the IDamageable when I use GetComponent<IDamageable>(), currently I'm using Unity 2019.3.3f1. About the support: https://unity3d.com/fr/unity/whats-new/unity-5.0 found this from here: https://stackoverflow.com/questions/52459094/unity-using-components-as-interface) Code (CSharp): public interface IDamageable { void ReceiveDamage(float damageValue, StatsManager.DamageType damageType); } Code (CSharp): private void OnTriggerEnter(Collider other) { if (other.GetComponent<StatsManager>()) { IDamageable damageable = other.gameObject.GetComponent<IDamageable>(); // Tried using: other.GetComponent<IDamageable>(); // Tried using directly here: damageable.ReceiveDamage(parameters); damageManager.DamageTarget( damageable, statTarget.CalculateDamageDeal(), statTarget.currentDamageType); } } This code below is being used in another script called DamageManager Code (CSharp): public void DamageTarget(IDamageable target, float damageValue,StatsManager.DamageType damageType) { if (target != null) { target.ReceiveDamage(damageValue, damageType); } else { Debug.Log("IS NULL"); } } And this is the error that appears if I remove the IF statement from above: NullReferenceException: Object reference not set to an instance of an object DamageManager.DamageTarget (IDamageable target, System.Single damageValue, StatsManager+DamageType damageType) (at Assets/_Scripts/System/Characters/DamageManager.cs:42) DoDamage.OnTriggerEnter (UnityEngine.Collider other) (at Assets/_Scripts/System/Characters/DoDamage.cs:27) I Can't find the solution for this problem why is this happening? Can this be related to the parameters I had put in the interface?
This absolutely works for sure. You didn't post the code for the class declaration header for the MonoBehavior that implements this interface. Are you sure that you put that MonoBehavior on the GameObject where you're doing the GetComponent<IDamageable>() ?
Sorry for my lack of knowledge by 'class declaration header' do you mean this: public class PlayerStats : MonoBehaviour, IDamageable if so here's the other code: Code (CSharp): public class PlayerStats : MonoBehaviour, IDamageable { public void ReceiveDamage(float damageValue, StatsManager.DamageType damageType) { float defType = 0; float finalDamage = 0; if (damageType == StatsManager.DamageType.physical) { defType = physicalDef; } else { defType = magicalDef; } finalDamage = damageValue - defType; if (finalDamage < 0) { finalDamage *= -1; } currentHP -= finalDamage; } } I'm using this same code on the Enemy script and confirmed that the script PlayerStats are inside the GameObject for some reason the image is not showing I will try to post a link below: https://imgur.com/a/ALQE1BJ
In your middle code blurb in the first post, I see you getting a StatsManager object off the same place (other) where you're getting the IDamageable object. Is that correct? A manager implies one thing shared across the game, whereas an IDamageable implies an actor. Are you sure you don't mean to just do a GetComponent right there on yourself, you being the one that stepped into the trigger and received this OnTrigger call??
OMG can't believe it was that condition stopping everything: if (other.GetComponent<StatsManager>()) Because the script StatsManager is on a child GameObject and the condition seems to can't reach or find this script, but strangely enough I verified the code inside this IF statement with the Debug.Log inside like this: Code (CSharp): private void OnTriggerEnter(Collider other) { if (other.GetComponent<StatsManager>()) { IDamageable damageable = other.gameObject.GetComponent<IDamageable>(); Debug.Log(damageable); } } and the console still printed NULL showing that this condition passed and went inside the { } (forgot the name of this type of brackets) below the IF condition for some reason. But for now it seems that it solved a 'part' of the problem and the damage is being applied now, because testing here sometimes shows that the IDamageable function is null here: Code (CSharp): public void DamageTarget(IDamageable target, float damageValue,StatsManager.DamageType damageType) { if (target != null) { target.ReceiveDamage(damageValue, damageType); } else { Debug.Log("NULL"); } } Anyway thanks for the help.