Let’s say I want to create an enemy for my game, which should implement pre-defined behaviour.
In what form would I pre-define that behaviour? If there was Behaviour for:
patrolling (subclass needs to implement Transform of patrol points)
Chasing (subclass has to implement bool canSeeTarget)
how would I make an Enemy implement one, and, more importantly, both of them:
class EnemyA
{
//Should Patrol & Chase
}
class EnemyB
{
//Should Only Patrol
}
I have tried using interfaces for this and inheriting the enemy class from both of them:
public interface ICanPatrol
{
Transform[] patrolPoints;
}
public interface ICanChase
{
bool canSeeTarget;
}
This, however, also failed, because “Interfaces cannot contain Instance Fields”; since Unity doesn’t support multiple inheritance either multiple abstract classes are also not an option.
I would appreciate another effective way of solving this problem or correction in my code, feel free to point out any stupid mistakes.
Thank you in advance.
You dont need to reinvent the wheel. There are design patterns that have been thought up to solve problems like these and that a knowledge of will give you a cohesive idea of how to approach problems.
Try the strategy pattern.
As an aside if the choice is use properties or have them exposed in the editor I will always chose properties. There are a million and one ways you can conveniently set and view the values of game objects (at both compile and runtime). The alternative to properties i.e. getter/ setter methods are just not worth entertaining especially since thats only a small part of what properties offer. The use of interfaces being one.
Another thing you can do is use polymorphism in conjunction with composition. That way you can make the actual “on-monobehavior” member a field and swap out the functionality even at runtime.
Also: An interface doesnt have to be an “interface” it can be a class … abstract or otherwise that another class conforms to.
An interface is thus a type definition; anywhere an object can be exchanged (for example, in a function or method call) the type of the object to be exchanged can be defined in terms of one of its implemented interfaces or base-classes rather than specifying the specific class. This approach means that any class that implements that interface can be used.
I’m not sure what’s your actual goal here. A “behaviour” is logic or actions which determine the behaviour of an object. Your interfaces do not contain a single method / function. You try to just define data. The question here is, what do you intend to do with those “interfaces”? Who is going to use those interfaces? Note I said “use” not “implement”. If you just want to use interfaces to group data for different behaviours, that’s not what an interface is meant for.
Interfaces are meant to construct a “contract”. So a class that implements that interface is guarateed to have certain methods and property available. If you just want to ensure that other classes can query “ICanPatrol” and be able to set or get a list of transforms, that can be done with a property. Properties are just a pair of a set and a get methods.
So you can use your interfaces to get access to a certain “field” of data. Though I’m still not sure how you want to use them.
public interface ICanPatrol
{
Transform[] patrolPoints {get; set;}
}
public interface ICanChase
{
bool canSeeTarget {get; set;}
}
Your title specifically asks for reusable “behaviour”. As I said interfaces only form a contract to ensure the existance of certain methods / properties. The actual behaviour (the logic, the method body) has to be implemented in an actual class. If you want to combine several behaviours you actually need some sort of FSM (finite state machine), Behaviour tree, Markov chain or some other behavior selection algorithm. Unity’s idea of a MonoBehaviour does already seperate different behaviours into seperate components. However if you have multiple behaviours which interfere each other you need some kind of control / decision mechanism.