Interaction system

Hi, I am making a game and I am working on the interaction system. So I made an interface in order to implement it for my different classes:

public interface IInteractable {

    bool isEnable { get; }
    float interactionDistance { get; }
    Sprite interactionIcon { get; }
    string interactionName { get; }
    bool Interact();
    void EnableInteraction(bool active);
}

So I implement this one on my different scripts (Chest, Pickable Item …) but I would like to each class calculates the distance between the player and itself. The problem is, these objects don’t share the same class or parent class that why I am using interface.

My question is: Should have to set an update function in each class to detect the player or can I have a script which has an update method calculing the distance between the player and all interactable objects ?

I hope to be clear enough.

Have a good day :wink:

I wouldn’t make the objects care about distance to a player. What if in the future you had a party of people and you could send only one of the people over to interact? Or even for some NPC to interact?

Instead, the thing doing the interaction would ask how close it needs to be (your interface above), then compute the distance.

Remember that all GameObjects have a Transform giving you position, etc. It’s almost like every GameObject already has this super-valuable interface built into it.

By calculating the distance between the object and the player, I meant, check if the distance is under the interactionDistance of my interface. Maybe It wasn’t enough clear.

My game is a solo game so I don’t care about other player, the only thing is, is it possible to make a script that check for all scripts cantaining the IInterractable interface, check if the player is close enough to interract or should I write this code in every script ?

Option 1: player checks close by interactables
Option 2: every single interactable checks if close to player

Here’s my question…

If every interactable is checking with the player. How does an interactable drop out of queue?

What I mean is… say the player is near 2 or more interactables at once who all succeed the distance check. If the play is doing the testing… well you just take the nearest, or the first, or whatever. But if the interactable is doing the testing… how does it even know other interactables are near?

Now the interactables need to not only know the player is near, but also know what interactables are also near the player. You’re now doing this work multiple times for every interactable.

Instead if the player is doing it… it just calculates the near entities and reduces by distance.

Or at least, that’s what I do:

(this is from one of my games)

(this is a slap-dash example I threw together as an example to a user here on the forums. It uses trigger colliders because that’s what they were doing in their OP)

I just don’t have it where each item has a distinct available distance. But that’s fine… when you reduce the list by distance instead of checking near by the player configured value, check it by the item configured value made available by your IInteractable interface.

Thank you for your reply, I will do each interaction will check for the player because each intercation has its own interaction distance and it wil be easier to manage.

To answer to you question, I don’t take the closest on, if an interaction is close enough, it adds itself to a list of interactions displayed to the player. He chooses among this list which one does he want to interact with. Then, if the interaction is to far, it remove itself from the list.

Thanks to that, each interaction has its own interaction distance, It’s very helpfull for instance in a place where there are a lot of interactions.

Normally we don’t do things like this. I recommend the standard way:

  • have a trigger collider on the interactable prefab
  • upon entering the trigger switch to “possible interaction” state
  • upon exiting the trigger switch to dormant state
  • when it is in “possible interaction” state, you need to check what’s in the front of the player (first raycast hit forward relative to the player rotation)
  • if an interactable is in the front of the player, show its tooltip and interaction button/key/etc.

This way you don’t need distance in code, you have a trigger collider which enables you to edit the distance visually. If you want to leave the object visible but disable the interaction, all you need to do is disable the collider. It handles multiple interactive objects crammed in small space since all of them will be in “possible interaction” state, but only one of them will be in the front of the raycast. Also this way you do not need a costly Update loop for every single item.

In general:
In Unity, you need to think about the whole problem-space at once instead of only thinking about the code part. Sometimes there are better solutions or even only possible ones if you combine your code with visual or object elements.

I agree with you with some parts like, think global for gameplay and code and that exactely why I am doing that.

I am making a game on mobile in 3D and I think, use trigger collision is not an good idea if 2 items are really close, how to select which one I want to interact with. For me the only way is to let the player doing this choice by an UI element displaying all available interactions.

In my case if I want to disable the interaction I just have to check a bool statement in the inspector or using script.

But I am ok with you, it’s not very easy to use since it means to implement the function for each object.