[GAME] Interacting with objects while in area2D and switching scenes

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By GunPoint
:warning: Old Version Published before Godot 3 was released.

So i have a kinematicbody as my player
When the player goes near a door, a button shows up what key he needs to press to go through that door.
So i made an area2d node around the door. When the player enters that area the image of the button shows up. I did that well
Now i want to check if the interact key is pressed while the player’s inside that area
I tried with the signal _on_area_body_enter and i tried to print something when the player enters that area and pressed the interact key:

func _on_area_body_enter(body):
     if body.get_name() == 'Player':
     if Input.is_action_pressed('interact')

The ‘interact’ key is set to be ‘E’ key.
That doesn’t work.
Also, when the interact button is pressed i want to change the scene. I need to initialize the scene first? How?
(Im new to Godot)…

:bust_in_silhouette: Reply From: eons

That can be done in many ways.

One could be to give a reference of the door to the player when body_enter, then make the “open door” or “action” input always work regardless the referenced object so it can trigger anything, not just doors.

When the player tries to trigger something, if null can make a sound or ignore it, if there is something, try to execute a common function on these objects (you can do a group check).

Then null the reference when body_exit.

How to change scenes will depend on your design, if you want to cut a branch of your scene or change all, there is a demo about scene change that uses an autoloaded script but can be done directly from the tree.

Check docs to understand how the scene tree works:

Im going to try that. That’s a good idea! TY

GunPoint | 2017-10-26 12:20

Can you give me a short example? I can’t figure it out

GunPoint | 2017-10-27 18:51

On door body_enter check if the body can interact with doors (is in a group that does that), then do something like body.set_active_object where a reference to the door is passed.

On player (or whatever body) action to open door, check if that active object is not null and execute it’s function to activate it like active_object.activate() (the function to atually open the door).

Other way to make it is adding a “interactive detection area/raycast” to the player, and make the player detect the objects directly, but depending on the design this can be straightforward or more complicated.

eons | 2017-10-28 15:13

:bust_in_silhouette: Reply From: Mhndra

I usedifstatements with a boolean Area2D.overlaps_body(playernode) instead of _on_area_body_enter() function

:bust_in_silhouette: Reply From: ccpixel

I know this is old, but I also struggled with this so thought I would post my solution.
I was able to handle this entirely in the script attached to the Player node.

In _physics_process(delta), I have some code to handle movement/animation and then I call move_and_collide. The object this returns also contains the information about the object the player collided with (the door). I pass this collision object to a function like the following:

    1    func handle_collision(collision):
    2    	if Input.is_action_pressed("interact"):
    3    		var col = collision.collider
    4    		if col.get_parent().name == "buildings":  
    5      			var indoor_scene = "res://scenes/buildings/interiors/%sIndoor.tscn" % col.name
    6      			get_tree().change_scene(indoor_scene)

Line 4 should be some condition that ensures this is actually a door we are colliding with, in my case this works. Using a group may work better for you. Line 5 constructs the name of the new scene to load. I named the interior scene for all of my buildings as <building_name>Indoor.tscn so that this scheme would work.