Objective system based on events

Hi, I wants to create a system of objectives to be showed at a given level. Unfortunately when the event is triggered the console log is not displayed.
Maybe my factory is wrong or in Objective class constructor I must add delegate for specific event for objective.
I wants to make it as professional and flexible as possible so if anyone has ideas on how to improve this please let me know

In ObjectivesManager in Start method is create Objective objects.

Factory class:

using System;
using System.Collections.Generic;
using UnityEngine;

public abstract class ObjectiveNameFactory
{
    public static readonly Dictionary<string, Action> objectiveHandlers = new Dictionary<string, Action>()
    {
        {"BuildBuilding", delegate { EventsManager.Instance.BuildingComplete += TestBuild;  }},
        {"GatherResource", delegate { EventsManager.Instance.BuildingComplete += TestGather;  }},
        {"ResearchTechnology", delegate { EventsManager.Instance.BuildingComplete += TestResearch;  }}
    };

    private static void TestResearch(GameObject obj)
    {
        Debug.Log("Work! " + obj);
    }

    private static void TestGather(GameObject obj)
    {
        Debug.Log("Work! " + obj);
    }
   
   
    private static void TestBuild(GameObject obj)
    {
        Debug.Log("Work! " + obj);
    }
}

Objectives class:

using System;

[Serializable]
public class Objectives
{
    public string objectiveID {get;}
    public int goalAmount {get;}
    public int currentProgress {get; private set;}
   
    public Objectives(string objectiveID, int goalAmount, int currentProgress)
    {
        this.objectiveID = objectiveID;
        this.goalAmount = goalAmount;
        this.currentProgress = currentProgress;
    }

    public void IncreaseProgress()
    {
        currentProgress++;
    }
}

Objectives Manager:

using System;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using Random = UnityEngine.Random;

public class ObjectivesManager : MonoBehaviour
{
    public List<Objectives> ObjectivesList = new List<Objectives>();

    [SerializeField] private TextMeshProUGUI objectiveListTextMeshPro;

    private void Start()
    {
        CreateNRandomObjectives();
    }

    private void CreateNRandomObjectives()
    {
        for (int i = 0; i < 5; i++)
        {
            int rnd = Random.Range(0, ObjectiveNameFactory.objectiveHandlers.Count);
            Objectives objectives = new Objectives(ObjectiveNameFactory.objectiveHandlers.Keys.ToList()[rnd], Random.Range(1, 20), 0);
            ObjectivesList.Add(objectives);
            objectiveListTextMeshPro.text += (objectives.objectiveID + " " + objectives.currentProgress + "/" + objectives.goalAmount) + Environment.NewLine;
        }
    }
}

Events Manager:

public class EventsManager : MonoBehaviour
{
    public static EventsManager Instance;
  
    public event Action<GameObject> BuildingComplete;
    public void OnBuildingComplete(GameObject building) { BuildingComplete?.Invoke(building); }
  
    public event Action<GameObject> GatherComplete;
    public void OnGatherComplete(GameObject sourceDeposit) { GatherComplete?.Invoke(sourceDeposit); }
  
    public event Action<GameObject> ResearchedTechnology;
    public void OnResearchedTechnology(GameObject labBuilding) { BuildingComplete?.Invoke(labBuilding); }
  
    private void Start()
    {
        Instance = this;
    }
}

You have to invoke the handler functions. They are not registering to the BuildingComplete until called.

Can you say what specifically needs to be done? I don’t have much experience with delegates and events and I’m getting a bit lost with them.

void Awake()
{
    foreach (var handler in ObjectiveNameFactory.objectiveHandlers.Values)
    {
        handler();
    }
}
1 Like

Thanks you.

I have another question, how to make the class Objectives run the method IncreaseProgress() when the event corresponding to the Objective is triggered, for example EventsManager.Instance.BuildingComplete() then all Objectives with the ID “BuildBuilding” run the their method IncreaseProgress()?