I am coding an interaction system in Unity that does things based on whether the player taps interaction, or holds interaction. Each object holds their own scripts of how a player can interact with them and what happens (e.g., they can physically lift an object, add an object to their inventory, open/close a door, etc)
What I want is for the interactable_object
to call component scripts that have been added to it and categorized as tapInteraction
or holdInteraction
, but I also want the component scripts to be separated from how they're called (e.g., they might be called via tap or hold, it shouldn't matter).
If I use interfaces, the tapInteraction
could check for GetComponent<ITap>()
and the holdInteraction
could check for GetComponent<IHold>()
, but then wouldn't each action need separate scripts defined as Lift : ITap
and Lift : IHold
? I feel like there would be a lot of repetition.
I'm wondering if there is some better way to go about this.
EDIT:
Thank you very much for the input DMGregory and Alex F!
I ended up going with an interface approach similar to what Alex F answered, but with two key differences:
- It was very important to me to have the actions as components on the gameobject since a specific action (e.g.
Lift
orAddToInventory
) would have a large amount of customization from object to object. - I also wanted the interaction to return a status as to whether it succeeded or not.
As such I created a base class Interaction
that implements the interface IInteraction
with a bool TryInteraction
method, and registers/deregisters itself to an interactable_object
via OnEnable
and OnDisable
as the tapAction
or holdAction
depending on if that Interaction is set as a tapAction or holdAction.
InteractionLift
and InteractionInventoryPickUp
inherit that base Interaction
class, they implement the TryInteraction
interface, and depending on their parameters will register themselves to a interactable_object script as either the hold or tap action. Then the interactable_object
fires the hold or tap TryInteraction
accordingly.
Lift
implementIInteraction
, and then havepublic IInteraction tapInteraction;
andpublic IInteraction holdInteraction;
. Then you can (maybe, again, not great with interfaces) set these in the editor for the maininteractable_object
script, without assigning these scripts to the object itself. (No idea if this would actually work, which is why it's not an answer - just a thought.) \$\endgroup\$