how to make the player interact with an npc

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Stoica Alex

Ok, so guys, I need help to make the Player interact with an NPC, now the thing is the dialog system itself is not a problem, I have a plugin for this, and its working, the problem is that how can I load that scene on viewport in my main level when I collide with the NPC area 2d and also I need to press E to interact with it, only then my dialog scene must load.

:bust_in_silhouette: Reply From: Mario

There are lots of different ways to solve this.

Here’s what I’d setup:

  • Create a new scene inheriting from Area2D and call it Interactable.
  • Set the Area2D’s collision layer and mask to a new, unused one (you can go to your project settings and call it “Interaction”, if you want).
  • Attach a script to the Area2D.
  • Connect the Area2D’s signals for entering/leaving areas to new functions and add a new variable (e.g. partner) that’s set set to the entering body (or null upon leaving).
  • Add a new signal on_interact and a simple function _interact() emitting said signal.
  • Add a new function (e.g. interact()) and within it check to see if partner has a valid value. If it has one, call partner._interact().

Now you’re done:

  • Add an instance of your Interactable scene to your player and any NPC or interactable object (like signs). Make it so they can touch each other when close enough. You’d typically make the player one as big as the player and the others so they include the area where an interaction should be possible.
  • In your NPC connect the on_interaction signal to load/display your dialog and you should be set, unless I missed something typing this out.

Bonus Thing 1: I remember seeing a very similar approach (without signals I think) made by DevDuck, explained in this DevLog for “Dauphin”. The interesting part starts around 6:15.

Bonus Thing 2: Rather than using the variable partner as a simple 1:1 connection, you could also use an array to collect multiple interactables, then in interact() iterate over all of them.

Bonus Thing 3: The design above should make it really easy to emit additional signals whenever an area is entered/left you can listen to, to connect stuff like visible interaction prompts (like “Press E to ”).

thanks, man really helpful :smiley:

Stoica Alex | 2021-04-08 17:09