Hello i'm working on a Unity game and i would like to create living entities.
To perform this, i want to create an interface for all entities having health
Here is my interface for LivingEntities:
public interface ILivingEntity
{
public float Hp { get; protected set; }
public float MaxHp { get; protected set; }
public float HpRegenPerSecond { get; protected set; }
public event EventHandler Event_died;
protected virtual void Awake()
{
MaxHp = Hp;
}
protected virtual void receiveDamage(IAttack attackSource)
{
Hp -= attackSource.damage;
watchForEntityDeadOrNot();
}
protected abstract void watchForEntityDeadOrNot();
protected void regenHp()
{
Hp = Time.deltaTime * HpRegenPerSecond;
if (Hp > MaxHp)
Hp = MaxHp;
}
}
The point is:
- I need the hp to be public in get
- I want to give code in my interface for the hp regeneration per second (to not re implement the same code in each living entity)
- I want the hp to be set only from the living entities themself
I saw tricks like this:
in interface:
public float Hp{get;}
and in implementation:
public float Hp{
get{code...}
protected set{code...}
}
but in my case, if i define the setter only in the child class implementation, i'm not able to give any code for my 'regenHp' method in interface.
How to perform this ?
CodePudding user response:
Rather than using an abstract base class as was suggested in a comment, you can leverage Unity's built in component design which is the standard way of solving such a problem. Its common for game objects to be composed of many components.
You can define a shared component like:
public class LivingComponent : MonoBehavior
{
...
}
And then depend on it in your main components:
[RequireComponent(typeof(LivingComponent))]
public class SomeLivingThing : MonoBehavior {}
And if its important that you still have a read-only interface, you can do that too:
public interface ILivingEntity {
// Getters only here
}
public class LivingComponent : MonoBehavior, ILivingEntity {
// Implementation
}
// In some other code:
var hp = obj.GetComponent<ILivingEntity>().Hp;