- Home /
Alternative inheritance
Hi all, I’m new in Unity. I have a question about inheritance and prefab management.
In my game i want to use same character as player or enemy: for example I can choose a wizard as player and fight against orcs, that are enemies. In the following match, to fight the new villains, I want to change character and replace my wizard with an orc.
I created two classes: PlayerBehaviour and EnemyBehaviour.
Every character has his own class, like wizardBehaviour, orcBehaviour, goblinBehaviour…etc…, and has to inherit from PlayerBehaviour or EnemyBehaviour.
I created two versions of same script: wizardEnemy and wizardPlayer (that are identical) and in my resources folder I have two copies of the same character, one with attached the “player version” and the other one with “enemy version”. it seems to me that it is inefficient, so, is there another way to do it? Is there a way to make my characterBehaviour inherit from EnemyBehaviour, if I want to use the object as an enemy, or PlayerBehaviour if I want to use the object as player without creating a lot of copies of the same thing?
Answer by Shrimpey · Feb 18 at 03:23 PM
There are several ways to deal with this, I'm not gonna post exact answer, but give you some direction for further research. What you've stumbled upon is called "Diamond problem in C#" and is usually solved by using interfaces instead of classes.
Another approach would be to rethink your whole structure and maybe use two classes instead of one, where one of them has an object of the other class inside. It really depends on methods and variables that you want to have there.
Hope that helps at least a bit in further research :)
thanks a lot for the ideas!
I have deepened the discourse of the interfaces but I don't understand how I can use them to solve this problem. Since I can only declare methods, without being able to define them, I would still need two classes in which to define the methods, called "PlayerBehavior" and "EnemyBehavior".
The classes of the various characters must have one of the two previous behaviors and add specific functions for each character, so using the interfaces I would still have to define the methods every time. I am not very familiar with interfaces and how they work, How could I use them in this case?
If you have lots of methods to inherit, then I think that in your case the most suitable solution would be something like this (still using classes):
> Abstract Behaviour class <- PlayerBehaviour and EnemyBehaviour inheriting from that class.
> Abstract FighterType <- WizardType, OrcType, etc. inherit from that.
And then in your Abstract Behaviour you have variable of type FighterType that defines which type is currently selected. You can then have something like this:
public abstract class Behaviour{
protected FighterType fighterType;
[...]
protected virtual Move(){}
}
And then specify different behaviour for enemy and player
public abstract class PlayerBehaviour : Behaviour{
[...]
protected override Move(){
fighterType.Move(Input.MousePosition()); // This is different Move(), it would be in FighterType class definition and overriden in WizardType, OrcType, etc.
}
}
public abstract class EnemyBehaviour : Behaviour{
[...]
protected override Move(){
fighterType.Move(new Vector3(1f,0f,0f));
}
}
This way you will be able to specify "fighterType" movement independently from Behaviour. You can then use different fighterTypes like wizard/orc in that class that will perform different things under the hood. You could also use Scriptable Objects for that so that you could predefine variables for each fighterType in inspector and just drag them onto movement script (enemy or player one).
Thank you for your help, I think I will use this approach, it seems to me very clear and efficient!