Improving the Interactable system within my game

I’m working on a big update for my Unity game. I’ve got these interactable’s in my game and I want to update the code of these interactables.
An interactable is an object the player can interact with, examples: a wire, a pile of dirt, a tree, a fusebox, wooden barricades.

Items like the pliers / shovel described in this post are both an Item and Interactable. Item inherits from Interactable.

One interactable in my game is a wire that the user has to snap using the pliers that he can find in my game.
Another example is the user has to find a shovel, with this shovel he can dig up a small chest hidden under the dirt.

In MOST instances an interactable needs the following:

  • To check if the player has a certain Item in it’s hands to compare if the user has the correct tool to interact with the interactable. (So to check if the user has a shovel in order to dig.)
  • To give the user a message, like give the player info on what he has to do eg. “You have to cut the wire using the pliers”.
    We do that with a LocalizedString + _onShowMessage event.
  • Play an audio when an action is performed using AudioCue.PlayAudioCue().

Now as you can see in the examples, there are some similarities.
Often I want to broadcast a message.
Often I want to check for an item in the players hands.
Often I need play an audio cue.
However not always, but often.
It seems to counterproductive to write a lot of the same code for each Interactable.

I was thinking about another Abstract class that inherits from Interactable.
So for example a class that forces the player to implement both the StringEventChannelSO so we can broadcasts messages
and also one LocalizedString that is given as the message.
However sometimes I need 2 or more messages to broadcast instead of one, but not always.

I’m not even sure how I should write such a class, something with a List would be possible I guess.

I also thought about an option of having the following in an extendable Interactable class:

  • 1 audio cue
  • 1 localized string
  • StringEventChannelSO variable
  • ItemSO variable

But again, I don’t need always need everything, it seems messy to add so much extra references to a GameObject in the inspector,
when that specific Interactable don’t need it.
This post is mainly me thinking out loud and hoping some of you guys can give me pointers on what I should do.
My goal is to be able to create more clear Interactables without having to write the same code over and over again for each Interactable
while not having to add a lot of unused references in the Inspector within Unity.

I don’t think having a few empty slots in the inspector is as big a problem as you’re making it. What you’re describing sounds like it’d require no subclassing an no more code than what fits on a screen. Just a bunch of if (audioCue) Play(audioCue);.

Those if-checks are not expensive at the scale of “a few checks at max on the frame you clicked a button”, and having the interactable as a simple thing instead of writing a class for each one is probably a lot more manageable.

You could write a custom reaction class that uses SerializedReference + custom inspector fun to be able to both play sounds, send localized strings, play particle effects, and whatever, and then have a list of those. We have done that, and it’s very great for designers to be able to just drag different kinds of effects into a list and then have it just work, instead of having to have one slot for audio, one for particles, etc etc., but that takes a bit of work and it doesn’t sound like you’re at the scale where that work is required.