#Interaction help

1 messages · Page 1 of 1 (latest)

swift shadow
#

Different roles require different interactables and interacting components. I have trouble because they are sometimes intersecting with each other despite their different layers and masks ;;

#

Scripts overview

Hack_interactable - The one that the hacker can interact with (Lock)
Hack_interacting_component - The node that the hacker has (Key)

Dev_interactable - The one that the dev can interact with (Lock)
Dev_interacting_component - The node that the developer has (Key)

TaskArea - The one being interacted with (Contains both hack_interactable and Dev_interactable)

#

#Taskarea.gd

extends StaticBody2D

#This is the interactable object.

@onready var Dev_interactable: Area2D = $dev_interactable
@onready var Hack_interactable: Area2D = $hack_interactable
@onready var sprite_2d: Sprite2D = $Sprite2D
@onready var CrewScreen: Button = $CanvasLayer/Button1
    
func _ready() -> void:
    _crewmate_interact()
    _hacker_interact()

func _crewmate_interact():
    Dev_interactable.interact = Dev_on_interact  # Assign function to interaction
    Dev_interactable.connect("area_entered", Dev_on_area_entered)
    Dev_interactable.connect("area_exited", Dev_on_area_exited)
    CrewScreen.visible = false

func Dev_on_interact():
    print("Interacted")
    CrewScreen.visible = true

func Dev_on_area_entered(area: Area2D):
    if area.is_in_group("Developer") :
        print("Entered:", area.name)

func Dev_on_area_exited(area: Area2D):
    if area.is_in_group("Developer") :
        print("Exited:", area.name)
        CrewScreen.visible = false

func _hacker_interact():
    Hack_interactable.interact = Hack_on_interact  # Assign function to interaction
    Hack_interactable.connect("area_entered", Hack_on_area_entered)
    Hack_interactable.connect("area_exited", Hack_on_area_exited)
    CrewScreen.visible = false

func Hack_on_interact():
    print("Interacted")
    CrewScreen.visible = true

func Hack_on_area_entered(area: Area2D):
    if area.is_in_group("Hacker") :
        print("Entered:", area.name)

func Hack_on_area_exited(area: Area2D):
    if area.is_in_group("Hacker") :
        print("Exited:", area.name)
        CrewScreen.visible = false

lunar dirge
#

What's the code for the actual object you're interacting with?

wide wasp
#

Yeah the problem definitely lies between the else you showed, and the hack_interactable_2d.gd script

swift shadow
wide wasp
#

Can you show the code for both of these ?

swift shadow
#

Ok ^^

#

#Hack_interacting_component

extends Node2D

#This is what allows the player to interact with an object.

@onready var interact_label: Label = $"../InteractLabel"
var current_interactions := []
var can_interact := true

func _input(event: InputEvent) -> void:
    if event.is_action_pressed("interact") and can_interact:
        if current_interactions:
            can_interact = false
            interact_label.hide()
            
            await current_interactions[0].interact.call()
            
            can_interact = true

func _process(_delta: float) -> void:
    if current_interactions and can_interact:
        current_interactions.sort_custom(_sort_by_nearest)
        if current_interactions[0].is_hacker:
            interact_label.text = current_interactions[0].interact_name
            interact_label.show()
        elif current_interactions[0].is_developer:
            interact_label.hide()
    else: 
        interact_label.hide()
                
func _sort_by_nearest(area1, area2):
    var area1_dist = global_position.distance_to(area1.global_position)
    var area2_dist = global_position.distance_to(area2.global_position)
    return area1_dist < area2_dist

func _on_interactrange_area_entered(area: Area2D) -> void:
    current_interactions.push_back(area)

func _on_interactrange_area_exited(area: Area2D) -> void:
    current_interactions.erase(area)

#

#Dev_interacting_component

extends Node2D

#This is what allows the player to interact with an object.

@onready var interact_label: Label = $"../InteractLabel"
var current_interactions := []
var can_interact := true

func _input(event: InputEvent) -> void:
    if event.is_action_pressed("interact") and can_interact:
        if current_interactions:
            can_interact = false
            interact_label.hide()
            
            await current_interactions[0].interact.call()
            
            can_interact = true

func _process(_delta: float) -> void:
    if current_interactions and can_interact:
        current_interactions.sort_custom(_sort_by_nearest)
        if current_interactions[0].is_developer:
            interact_label.text = current_interactions[0].interact_name
            interact_label.show()
        elif current_interactions[0].is_hacker:
            interact_label.hide()
    else: 
        interact_label.hide()
                
func _sort_by_nearest(area1, area2):
    var area1_dist = global_position.distance_to(area1.global_position)
    var area2_dist = global_position.distance_to(area2.global_position)
    return area1_dist < area2_dist

func _on_interactrange_area_entered(area: Area2D) -> void:
    current_interactions.push_back(area)

func _on_interactrange_area_exited(area: Area2D) -> void:
    current_interactions.erase(area)


lunar dirge
#

I'm still not seeing any is_developer variable nor function.

swift shadow
#

#Dev_interactable

extends Area2D

#This is the component that makes an object interactable.

@export var interact_name:  String = ""
@export var is_developer: bool = true

var interact: Callable = func():
    pass

lunar dirge
#

Aha, sorry. There it is.

wide wasp
#

Ok I found the problem

swift shadow
#

#HAck_interactable

extends Area2D

#This is the component that makes an object interactable.

@export var interact_name:  String = ""
@export var is_hacker: bool = true

var interact: Callable = func():
    pass

wide wasp
#

Whenever you enter any area, it goes in "current_interactions"

swift shadow
wide wasp
#

Do you know about groups ?

#

They might solve the problem you're facing with the is_developer and is_hacker booleans

swift shadow
wide wasp
#

Ok, so instead of using the is_hacker boolean for example

#

You do if yourVariable.is_in_group("hacker"):

#

And if you need to dynamically change what groups they belong to, you can also do that via code iirc

swift shadow
#

oh so I'll replace the current_interactions[0] with variable.is_in_group("hacker"):

wide wasp
#

current_interactions[0].is_hacker but yeah

#

You could even (not necessary but I like doing it that way) add an "interactable" group, and before adding anything to "current_interactions", you check for that group

#

Because nodes can be in any number of groups at the same time

lunar dirge
#

Another thing to consider is adding if current_interactions[0] is dev_interactable: and adding a class_name to your dev_interactable object to differentiate them. That way even if you do get a rogue area in the list, it won't crash the game.

wide wasp
#

Yeah the classname approach is even better
Only downside is that you can't change class_name at runtime

swift shadow
#

Oh I see I see. I think I'll go with the classname approach for now since I know this sounds stupid but I don't know which variable it is we're talking about, sorry :')) I only assigned the interacting components to their respective groups and not variables. Also, I don't think I'll have to change class_names during the game

#

Thanks a bunch!! I'll test it out now ^^

#

changes implemented ^^


func _process(_delta: float) -> void:
    if current_interactions and can_interact:
        current_interactions.sort_custom(_sort_by_nearest)
        if current_interactions[0] is dev_interactable:
            interact_label.text = current_interactions[0].interact_name
            interact_label.show()
    else: 
        interact_label.hide()

#

Will test it out now

swift shadow
#

I'm encountering a bug though, all the code reads is the _developer_interact and _hacker_interact

wide wasp
swift shadow
#

Wait hold on, I have a fix in my mind

#

I'm gonna try to implement it

#

it could be a simple layer and mask issue I think ?