Question

I'm working on a game with Unity3D coding C#.

Since I came to Unity from a pure OOP environment, component-based approach was meaningless to me. So for our weapon system, I went purely OOP with an inheritance tree and object hierarchy approach. The more I spent time with my code adding new features and stuff, the more inflexible I found this design is. So now I'm leaning forward to a component-based design.

I posted my problem here, asking whether it's good enough if I used a composition-over-inheritance approach, as suggested here by Mr.Jamora.

His solution sounds really good. But falls short simply if I had more than one weapon, implementing the same logic of lets say the Reload from IReloadable

public interface IReloadable
{
   void Reload();
}

public interface IUpgradable
{
   void Upgrade();
}

public interface IShooter
{
   void Shoot();
}

public SMG : IShooter, IReloadable
{
   void Shoot()
   {
       // shooting logic 1
   }
   void Reload()
   {
       // reloading logic 1
   }
}

public AssaultRifle : IShooter, IReloadable, IUpgradable
{
   void Shoot()
   {
       // shooting logic 2
   }
   void Upgrade()
   {
       // upgrade logic 1
   }
   void Reload()
   {
       // reloading logic 1 -- SAME LOGIC
   }
}

As you can see, there's code duplication, I don't like that. Can this be avoided? (in a clean, flexible way)

And in general, is this (composition over inheritance) a good way to approach making a weapon system in Unity? - Or it's better to use Unity's component-based approach, and make a Shooter and Reloadable components (Scripts) and attach them to my weapon gameObject?

Thanks in advance for your help.

Was it helpful?

Solution

Thanks for anyone who tried to help. I actually got a nice explanation from Jamora, at the same link I posted above [link]. But I never got the time to share it again.

However, I discovered that you can't make everything a component, for example, a Reloadable or a Shooter component. Unless all your weapons reload/shoot the same way, you can't create such components and attach it to them, cause if weapons reload/shoot differently, this means that this information should be in the weapon itself (ie an abstract Weapon with maybe an abstract Reload and Shoot methods) so the component doesn't know that info.

Another example, making a Usable script component to attach to your items. You can't do that, that doesn't make sense. Using a health item, is different from using a key to open a door. The using information is stored in the items themselves. Attaching Usable to an item, means that all items are used the same way.

I've also discovered that, inheritance is a must, even in Unity. But the bad thing is to just depend on pure object-hierarchy trees for all your designs. Instead, create mixes of small trees, implementing interfaces for different behaviors and create script components whenever you can.

OTHER TIPS

If your following Unity3D conventions and especially if your using javascript, its prefered (forced) to use Composition.

However it looks like your using C# in which case you have a choice.

As long as your not violating DRY, then it really depends on your preference. But unity is already set up to handle composition. (I on the other hand prefer inheritance)

Yes, composition is the best for reusable codes and prevents duplicate and copy paste codes. You didn't use composition, you only used inheritence and interfaces. The best procedure is to implement IReloadable Ishootable ,... interfaces and Reloadable1,shootable1,Reloadable2,shootable2,... classes that inherit IReloadable,Ishootable. Then you can use Reloadable1,shootable1,Reloadable2,shootable2,.. components for your weapons. So if you want to change anything, you only need to change one one component(for example Reloadable2)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top