Quick explanation: I have an objective system, its goal is to run and process objectives, for example wanting the player to go to a specific location or collect an amount of items.
the issue: So I am currently storing the nodes I need for my objectives in a dictionary with the key being a string and the value being a path to the nodes I need, I feel like there is a better way of doing it, I was thinking of utilizing signals but I am not an expert on using them, I was kinda thinking of somehow have the area3D have its own script that emits a specific signal with a keycode value (export var) and have the current objective listen to that keycode, I want to do something like this to avoid having links between nodes and should make it more dynamic, how do I go about doing this or something similar, also I am 100% open for even better ideas!
extends Node
@export var hud : CanvasLayer
# Holds objective nodes so we can connect them to the objective base class
@export var objective_configurations : Dictionary = {}
# Holds the logic, its a simple state machine that checks if the objective is complete
# or not and based on the information it returns we decide what happens.
var system = Objective_System.new()
func _ready():
# Have a setup function to config each objective
setup()
func _process(delta):
# does the state machine comparisions in a match statement
system.update()
func setup():
# Get the path for our area3D we want
var path_1 = objective_configurations.get("Location_1")
# get the node using the path
var node_1 = get_node(path_1)
# create a specific objective with name and discription attached
var objective_1 = Objective_Location.new("Go to pink area","You must find the pink area!!!")
# set any variables the objective might need in this case an area3D
objective_1.set_variables(node_1)
# and finally add it to the system so it can be processed.
system.add_objective(objective_1)
# same as the top but a different area3D
var path_2 = objective_configurations.get("Location_2")
var node_2 = get_node(path_2)
var objective_2 = Objective_Location.new("Go to the green area","Find the dangerous green area!!!")
objective_2.set_variables(node_2)
system.add_objective(objective_2)
as you can see I currently have a setup function that lets me do all the configuring but I feel like there is a better way of handling this, I simply want to setup to be just setting names and discriptions and maybe in the future some code key word for it to listen to.
class_name Objective_Location extends Objective
var Area : Area3D
var in_area : bool = false
func set_variables(_area : Area3D):
Area = _area
func start_objective():
Area.body_entered.connect(entered)
print(Name)
print(Discription)
func check_objective() -> States:
if in_area:
return States.Completed
else:
return States.Running
func completed_objective():
print("Objective " + Name + " complete!")
func entered(body):
if body is Player and Status != States.Done:
in_area = true
and this is the objective go to location class, the base class holds 3 functions, start, check and complete objective
You can make a dynamic objective system using groups instead of manually setting each one of you objectives.
For this, add the objectives nodes to a group through the Godot Interface:
Then, in the objective system, retrieve the nodes list using get_nodes_in_group
function and iterate through them, like this:
for objective_node in get_tree().get_nodes_in_group('guards'):
var objective = Objective_Location.new("Go to pink area","You must find the pink area!!!")
objective.set_variables(objective_node)
system.add_objective(objective)