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
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.
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.
AddToInventory) 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
OnDisable as the
holdAction depending on if that Interaction is set as a tapAction or holdAction.
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
IInteraction, and then have
public IInteraction tapInteraction;and
public IInteraction holdInteraction;. Then you can (maybe, again, not great with interfaces) set these in the editor for the main
interactable_objectscript, 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\$