#Interaction help
1 messages · Page 1 of 1 (latest)
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
What's the code for the actual object you're interacting with?
Wait >>
Yeah the problem definitely lies between the else you showed, and the hack_interactable_2d.gd script
It's the task.gd, the one I wrote up
Ohh
Can you show the code for both of these ?
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)
I'm still not seeing any is_developer variable nor function.
#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
Aha, sorry. There it is.
Ok I found the problem
#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
Whenever you enter any area, it goes in "current_interactions"
Oh
Do you know about groups ?
They might solve the problem you're facing with the is_developer and is_hacker booleans
Yeah, I've recently added the hacker and developer interacting component in their respective groups
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
If you need more details about them, here's a link to the doc : https://docs.godotengine.org/en/stable/tutorials/scripting/groups.html#managing-groups
Groups in Godot work like tags in other software. You can add a node to as many groups as you want. Then, in code, you can use the SceneTree to: Get a list of nodes in a group., Call a method on al...
oh so I'll replace the current_interactions[0] with variable.is_in_group("hacker"):
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
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.
Yeah the classname approach is even better
Only downside is that you can't change class_name at runtime
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
It works now, thanks ^^
I'm encountering a bug though, all the code reads is the _developer_interact and _hacker_interact
I'm not sure I understand, what are these ?
It can't seem to read when an area is entered. It's supposed to print something out
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 ?