How would I get around multiple inheritance for this instance?
Hey all, I've been really digging deep into the programming I'll need and I'm coming up empty on some important features.
Namely, I need (essentially and effectively) 2 classes for a character that command completely different things.
Class A should command stats and magic. Class B should command physical skills and weapons/armor.
There is a story reason for this, in case you are curious as to why I would do this, but I digress.
I looked around and while you can definitely let a script borrow from a few (via interface) with a comma in the x : y of the class, you can't then refer to that script in a separate script cleanly. In other words, multiple inheritance can't really happen (as many forum posts alerted me to once this happened to me).
So if I need a script to refer to these two individual parts... what exactly would be the best way to go about that? I'm incredibly stumped on how to join those two aspects in a coding sense.
Answer by jdean300 · Jul 08, 2016 at 08:34 AM
Favor composition over inheritance. Have two separate scripts, lets call them Magic and Physical. Then to refer to both classes you just need to get a reference to each component on the same object:
GameObject character = /*Get the character*/;
Magic magicComp = character.GetComponent<Magic>();
Physical physComp = character.GetComponent<Physical>();
Composition is definitely going to be the easiest way to accomplish this, but you can also do something like this:
public interface IMagic
{ /*magic stuff*/ }
public interface IPhysical
{ /*physical stuff*/ }
public interface IMagicAndPhysical : IMagic, IPhysical
{}
Alternatively, if you really wanted to have only one component class with multiple interfaces, but still refer to the interfaces separately:
public class Character : MonoBehaviour, IMagic, IPhysical
{}
//Then in some other code
GameObject charObj = /*get object*/;
IMagic magic = charObj.GetComponent<IMagic>();
IPhysical phys = charObj.GetComponent<IPhysical>();
//or if you wanted access to all the character stuff
Character char = charObj.GetComponent<Character>();
In the last example, magic, phys, and char are actually all the same object, but 'restricted' to different portions of the object.
I suggest you go with the first solution (composition). It is the easiest to work with. You say there is a story reason for why you would want multiple inheritance, but there is no reason I can think of why your code has to mirror your story. Your story can make it seem like a character is two different things at the same time, but your code does not have to handle that with multiple inheritance (which models an object being two things at once).
Thanks! I said there's a story reason, yes, but I had meant it in the sense that it needs two separate classes (in game classes, not the coding kind! I should have clarified, hah), not necessarily multiple inheritance. I'm still learning coding, so this is a very helpful answer.
Hmm, so after looking a bit more at this, I have to ask how I would use the GetComponent as in the first example.
For example, Script A has A's stuff, Script B has B's stuff, but then would Script C simply just have "GetComponent"? Or will I need specific code within A and B so that C can communicate with those parts? (As I said in another comment, I'm still a bit new, but that does seem like a very workable answer, so I'd like a bit more of an explanation if that's alright!)
GetComponent is not a function that you define - it is one that GameObjects and $$anonymous$$onoBehaviours inherit.
public class A : $$anonymous$$onoBehaviour
{
public void DoSomething()
{ /*Something A related*/ }
}
public class B : $$anonymous$$onoBehaviour
{
public void DoSomething()
{ /*Something B related*/ }
}
public class C : $$anonymous$$onoBehaviour
{
void Start()
{
//Get the object named "Player" in the scene
GameObject character = GameObject.Find("Player");
//Get a reference to the A/B components on the character object
A aComp = character.GetComponent<A>();
B bComp = character.GetComponent<B>();
//Do something with the components
aComp.DoSomething();
bComp.DoSomething();
}
}
Another way: assume that an object has all 3 scripts on it, A, B, and C:
public class C : $$anonymous$$onoBehaviour
{
void Start()
{
//$$anonymous$$onoBehaviours have this function to. It will get the A script on the same object as this script(C)
A aComp = GetComponent<A>();
}
}