How do i code dialog/interaction in general?

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

I’ve been struggling with this for weeks! All i can do is make an area 2D to detect when a body enters them: I cant trigger the actual interactions! Please help!!

:bust_in_silhouette: Reply From: tastyshrimp

I’m not sure I understand the problem, so I will describe one way to make an interaction happen.

First I’ll make a few assumptions, try to imagine it or make a demo project:

  • You have a player object with a RayCast2D pointing in front of it. (Can also be an Area2D, but i believe a RayCast makes the explanation easier)
  • You have a physics object you want to interact with, for example, a StaticBody2D.
  • The interaction will be triggered by the Player pressing a key in the keyboard.
  • The Interact key press is processed by the player in the _process or _physics_process methods with if Input.is_action_pressed("ui_interact")

Now to make the interaction itself happen:

  • The player is in front of the object we want to interact it. And in range of the RayCast2D, so the collision is happening.
  • In this case we get the colliding object from the RayCast2D, check if the object is the correct one by checking if it implements a functon or is in a group and call a function from it to tell it that the interaction is happening and it should do something.
    OR
  • We show a pop up in the screen
    OR
  • We cause our player to change color… the possibilities are endless!

As for code, our player code could look something like this:

func _physics_process(delta):
  if get_node("RayCast2D").is_colliding():
    var object = get_node("RayCast2D").get_collider()
    if object.is_in_group("Interactable") && Input.is_action_pressed('ui_interact'):
      object.do_something() #This would be where your inraction occurs

the error is probably because when copying it went as a space instead of tab.
And the object is whatever the ray cast 2d is colliding with. Can be any other Physics body or Area type node depending on how you configure the raycast, Body is the default.

tastyshrimp | 2019-12-22 12:34

Yes, I just figured that out myself! Thank you lots!
By any means, do you know how to stop movement while interacting? Do i just use motion = 0? Or make a var can_move?

Anastasia | 2019-12-22 12:39

there are many ways of doing that, you could stop processing the movement input all togheter by setting a flag while interacting, or stop calling move_and_collide/slide methods, or pausing the node.

tastyshrimp | 2019-12-22 12:42

Hello! I just checked the project today, and it didnt seem to work. i havent tested it before.
I have replaced “ui_interact” with “ui_accept” so that isnt a problem
the group name is also right

if get_node("RayCast2D").is_colliding():
	var object = get_node("RayCast2D").get_collider()
	if object.is_in_group("Interactebles"): 
		if Input.is_action_pressed('ui_accept'):
			print("Greetings!")

here is the code. im sorry if im being too insistent…

EDIT: It does work! sTILL having trouble with the raycast but Thank You!!!

Anastasia | 2019-12-24 11:56

Not sure what your problem is and I won’t be able to help you with more details. But here, I made a quick and dirty minimum collision with RayCast2D example, link.
Some details:

  • There is only 1 KinematicBody2D and a StaticBody2D
  • It uses the arrow keys to move around and space bar to interact
  • When interacting the color of the StaticBody2D changes
  • I added a Line2D as a child of RayCast2D to be able to easily debug it.

PS: Don’t forget to enable the RayCast2D. That node comes disabled by default.
Hope it helps.

tastyshrimp | 2019-12-24 12:25

:bust_in_silhouette: Reply From: Xtremezero

it’s very simple ,to create such interaction system:
1- first of all you need to connect the body_entered and body_exited signals to the AREA_2D object.
2- create functions to handle the interactions e.g( start_dialogue , end dialogue) , the first parameter is the name of the object that enters the AREA_2D , so you can check if it’s the player or any random moving object
3- implement your dialogue procedure in these functions

Note: your player should be any kind of a physics body with a collision shape in order for this to work

Example script - use it on Area2D node:

extends Area2D

func _ready():
	connect("body_entered",self,"start_dialogue")
	connect("body_exited",self,"end_dialogue")

func start_dialogue(body):
	if body.name == "player":
		print("greetings!")
	
func end_dialogue(body):
	if body.name == "player":
		print("good bye!")