Witam,
Tworzę do swojej gry system celów misji do wykonania na danym poziomie. Mam stworzoną fabrykę która przechowuje ID konkretnych celów misji oraz Action.
Problem polega na tym że nie wiem jak zrobić by w momencie wywołania pewnego eventu, na obiektach którego ID celu misji zgadza się ze zdarzeniem, wywołana została metoda z tej klasy.
Próbowałem w konstruktorze przekazać Action i potem dać Invoke ale chyba nie dokończa dobrze to działa.
Niestety słabo ogarniam te eventy i delegaty i jeśli ktoś ma rady jak to zrobić lepiej i elastyczniej lub wyjaśni jakoś przystępniej to będę wdzięczny za radę.
Fabryka:
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.GatherComplete += TestGather; }},
{"ResearchTechnology", delegate { EventsManager.Instance.ResearchedTechnology += TestResearch; }}
};
private static void TestResearch(GameObject obj)
{
Debug.Log("Work research! " + obj);
}
private static void TestGather(GameObject obj)
{
Debug.Log("Work gather! " + obj);
}
private static void TestBuild(GameObject obj)
{
Debug.Log("Work build! " + obj);
}
}
Objective class:
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, Action myDelegate)
{
this.objectiveID = objectiveID;
this.goalAmount = goalAmount;
this.currentProgress = currentProgress;
myDelegate.Invoke();
}
public void IncreaseProgress()
{
currentProgress++;
}
}
Objective manager
public class ObjectivesManager : MonoBehaviour
{
[SerializeField] private TextMeshProUGUI objectiveListTextMeshPro;
void Awake()
{
foreach (var handler in ObjectiveNameFactory.objectiveHandlers.Values)
{
handler();
}
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, ObjectiveNameFactory.objectiveHandlers[ObjectiveNameFactory.objectiveHandlers.Keys.ToList()[rnd]]);
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) { ResearchedTechnology?.Invoke(labBuilding); }
private void Awake()
{
Instance = this;
}