Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by MoltenShots · Jan 31, 2017 at 12:12 PM · componentmonobehaviourinterfacedesignbest practices

How to Use Components and Interfaces together?

I have just transitioned the way I build my player to components and I am wondering if I am using components and interfaces in the correct way. The way I decide if it should be a component or an interface is - if it will have a common implementation it's a component, if it will have a varying implementation, it's an interface. I.e. Health, health will behave the same no matter what it is attached to. However, OnDeath will be different for each thing it is attached to, so instead of having a Killable component, I have a IKillable interface that the object that is killable implements.

I have 4 main components which are held in the Entity Interface:

  • Health

  • IInput

  • EntityAnimator

  • Movement

My player implements the interface Entity, as all entities will have these elements (at least NPC and player entities)

Health can be buffed, and also damaged so I had it implement the IBuff and IDamageable interfaces.

An Entity can be killed, so I implement the IKillable interface.

My Observation

As I was writing this I came up with a different question/observation. I think I am on the kind of right approach in that if components will be different, and make them interfaces, but instead of having say IEntity implement IKillable, have a component - PlayerKillable and have THAT implement IKillable, and then have IEntity contain an IKillable component. Would that be the right way to handle components and interfaces? If so, the implementation I have below doesn't change much besides the fact that my current components will now implement a base component, correct?

Original Question

My question is - Should I be having these be interfaces? IKillable, IBuff, IDamageable, etc. Or should they be components themselves? The reason I have them as interfaces is because their implementation will change based on the entity. I think I may have answered my question there, but I also want to verify that I am going down the correct path before I get too far.

A followup question would be, I know entites will have Movement, Input, and Animations - however these will be different depending on if it's an NPC or player, so does it make sense to make all of them interfaces like I did for IInput and have the IEntity contain them? Or is there another way I should do it?

Another would be, using Health as an example, how do I differentiate between what should be an interface that the component implements, or a component that the component contains? What I mean by this is the example of IDamageable. Health will not be the only thing I have that is Damageable, an example would be Mana, mana is also Damageable, but in a different way than health would be (potentially), which is why I have it as an interface. What instances would I rather have a component instead of an interface using the example of IDamageable? How do I know when to use one or the other?

Code

Here is the related code -I left out the EntityAnimator and IInput, because I need to make it an IAnimator as players will be animated differently from enemies and because IInput is empty currently:

IDamageable

 public interface IDamageable {
     void OnHeal(int amount);
     void OnDamage(int amount);
 }
 

IKillable

 public interface IKillable {
     void OnDeath();
 }
 

IBuff

 public interface IBuff {
     void OnBuff(int amount);
     void OnDebuff(int amount);
 }


Health

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Health : MonoBehaviour, IBuff, IDamageable {
 
     public int MaxHitPoints = 10;
     public int EffectiveHitPoints;
 
     void Awake()
     {
         EffectiveHitPoints = MaxHitPoints;
         HitPoints = EffectiveHitPoints;
     }
 
     public int HitPoints
     {
         get
         {
             return hitPoints;
         }
         set
         {
             hitPoints = Mathf.Clamp(value, 0, EffectiveHitPoints);
             if(hitPoints == 0)
             {
                 gameObject.SendMessage("OnDeath");
             }
         }
     }
     private int hitPoints;
 
 
     // Event Listeners
 
     public void OnDamage(int amount)
     {
         //Debug.Log("Health.OnDamage: " + amount);
         HitPoints -= amount;
     }
 
     public void OnHeal(int amount)
     {
         //Debug.Log("Health.OnHeal: " + amount);
         HitPoints += amount;
     }
 
     public void OnBuff(int amount)
     {
         //Debug.Log("Health.OnBuff: " + amount);
         EffectiveHitPoints += amount;
     }
 
     public void OnDebuff(int amount)
     {
         //Debug.Log("Health.OnDebuff: " + amount);
         EffectiveHitPoints -= amount;
     }
 }
 

Movement

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Movement : MonoBehaviour {
 
     Rigidbody2D rigidBody;
 
     void Awake()
     {
         rigidBody = gameObject.GetComponent<Rigidbody2D>();
     }
 
     void OnMove(Vector2 movementVector)
     {
         //Debug.Log("Movement: " + movementVector);
         rigidBody.MovePosition(rigidBody.position + movementVector * Time.deltaTime);
     }
 
     void OnTeleport(Vector2 teleportLocation)
     {
         rigidBody.MovePosition(teleportLocation);
     }
 }

IEntity

 public interface IEntity : IKillable
 {
     Health Health
     {
         get;
         set;
     }
 
     Movement Movement
     {
         get;
         set;
     }
 
     IInput EntityInput
     {
         get;
         set;
     }
 
     EntityAnimator EntityAnimator
     {
         get;
         set;
     }
 }

 

Player

 using System;
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Player : MonoBehaviour, IEntity
 {
     private Health health;
     public Health Health { get; set; }
 
     private Movement movement;
     public Movement Movement { get; set; }
 
     private IInput entityInput;
     public IInput EntityInput { get; set; }
 
     private EntityAnimator entityAnimator;
     public EntityAnimator EntityAnimator { get; set; }
 
     void Awake()
     {
         Health = gameObject.GetComponent<Health>();
         Movement = gameObject.GetComponent<Movement>();
         EntityInput = gameObject.GetComponent<UserInput>();
         EntityAnimator = gameObject.GetComponent<EntityAnimator>();
     }
 
     public void OnDeath()
     {
         Debug.Log("I died");
     }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Is it possible to mark MonoBehaviour as EditorOnly 2 Answers

When do components of loaded prefabs get initialized? 1 Answer

Disabling GameObject doesn't disable components 0 Answers

Enabling multiple Monobehaviour Components in a game object 1 Answer

Any recommended books/resources on component-based design? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges