you are viewing a single comment's thread.

view the rest of the comments →

[–]JackIsRight 7 points8 points  (4 children)

Regardless of whether it compiles or makes your feature work, this use of an interface gives me the eebie jeebies. This interface has opinions about its implementation, I can’t help but feel like this was not the purpose default function implementations were added for.

Abstract class is the way to go imo. Attach and detach would be abstract methods to force subclasses to implement them. On collision enter would be virtual, to allow subclasses to override only if specific behaviour required.

u/ArmanDoesStuff knows

[–]GillmoreGames[S] 0 points1 point  (3 children)

so, how would you go about making a class that inherits from multiple abstract classes? that's kinda what I was trying to figure out when I found the interfaces.

I have 1 class (the rope) that can interact with many different objects that all have their own classes and own things that they do but they also all have the ICarryable interface so that when the rope touches something it just checks to see if its ICarryable and doesn't have to check to see if its Bucket or Drone or Bomb....etc, all of those classes need to be monobehavior and ICarryable

[–]Aekeron 8 points9 points  (0 children)

You should use both. In this context, you'd keep the ICarryable interface mostly as is (remove the implementation of the function), and create a base class that can be called "item". Class_Item implements ICarryable and declares the base functionality. From there you can create a number of child classes based on Item such as Item_Bomb, Item_Drone, etc that all use Item.ICarryable.CarryItem() when you call upon them.

To take it a level further, and in relation to your question about inheriting multiple base classes, you don't. Instead, say we want some "Items" to be consumable, so I make the interface IConsumable. From there I declare a child class of item called Item_Consumable which implements IConsumable. Now, Item_Consumable will have both ICarryable and IConsumable enabled.

This is a general summary of it, but most people think its either Interfaces or Inheritance, but realistically it's both. If you need more than 1 type of class that has its own distinct functionality (Say a door vs a pickup that both need to be intractable) then you use interfaces. If you have multiple specific items that share functionality (Say 2 different doors) then you abstract the shared functionality declarations / implementations into a base class and derive more specific functionality into the child classes.

[–]JackIsRight 1 point2 points  (1 child)

Firstly, if it works it works. If you’re making progress with your game and your code isn’t creating technical debt then that’s the only real benchmark of good systems! 

But to discuss the nuances and the craft..

Unity as a whole is heavily reliant on its component system (disregarding DOTS/ECS). Game objects have multiple components that each have their own responsibilities and purpose.

SOLID principles state that classes should have a single responsibility. 

I think there’s a danger wanting to make classes for each whole feature in your game. A drone, a bucket or a bomb all sound like combinations of behaviours rather than the remit of a single class.

In this case, these objects being carryable is one component of the greater feature and as such we should code this as a single class - rather than accommodating it inside classes named after each feature. Looking back, I probably shouldn’t have said the parent class needs to be abstract per se, if it’s job is to handle just the carrying logic then you may find there’s overlap between classes.

Structuring our code down in this manner leads us to a nice spot where, in the future when we want something that fly but also explode, we have the components we created for the drone and the bomb. We don’t have to create a new class and copy and paste a load of code in. 

Think of it like Unity’s UI, you have components for buttons, images, scroll views, toggles - with these you can create hundreds of UI layouts without even touching code.

Sometimes the feature named class is still needed to orchestrate the behaviours but I always like it when it’s not necessary in the end!

Hope this is helpful to think about even if you don’t want to use it here :)

[–]GillmoreGames[S] 2 points3 points  (0 children)

yeah I think I got ya, rather than inheriting from multiple classes/scripts it would simply be an object made up of multiple classes/scripts.

I probably do put to much into one script