Hello,
I’m trying to code some kind of EventManager to use events to change parameters into another script.
The EventManager.cs, attached to an empty object “EventManager” in the scene is coded as follow:
using System;
using System.Collections.Generic;
using UnityEngine;
public class EventManager : MonoBehaviour
{
private Dictionary<string, Action<Dictionary<string, object>>> eventDictionary;
private static EventManager eventManager;
public static EventManager instance
{
get
{
if (!eventManager)
{
eventManager = FindObjectOfType(typeof(EventManager)) as EventManager;
if (!eventManager)
{
Debug.LogError("There needs to be one active EventManager script on a GameObject in your scene.");
}
else
{
eventManager.Init();
// Sets this to not be destroyed when reloading scene
DontDestroyOnLoad(eventManager);
}
}
return eventManager;
}
}
void Init()
{
if (eventDictionary == null)
{
eventDictionary = new Dictionary<string, Action<Dictionary<string, object>>>();
}
}
public static void StartListening(string eventName, Action<Dictionary<string, object>> listener)
{
Action<Dictionary<string, object>> thisEvent;
if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
{
thisEvent += listener;
instance.eventDictionary[eventName] = thisEvent;
}
else
{
thisEvent += listener;
instance.eventDictionary.Add(eventName, thisEvent);
}
}
public static void StopListening(string eventName, Action<Dictionary<string, object>> listener)
{
if (eventManager == null) return;
Action<Dictionary<string, object>> thisEvent;
if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
{
thisEvent -= listener;
instance.eventDictionary[eventName] = thisEvent;
}
}
public static void TriggerEvent(string eventName, Dictionary<string, object> message)
{
Action<Dictionary<string, object>> thisEvent = null;
if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
{
thisEvent.Invoke(message);
}
}
}
The event generator is another object in the scene. The event is triggered when a certain variable reaches a certain value:
if (annualInib >= 0.95 * theIntegrator.IMax)
{
EventManager.TriggerEvent("stopStagione", new Dictionary<string, object> { { "kI", 0.3 } });
}
As the code above, when the annualInib is >= 0.95 * theIntegrator.IMax, the event is triggered and the parameter I want to change kI
is passed with the new value I want to set kI = 0.3
The listener is in another script where I need to change the parameter passed by the event and do some calculation (not complete code below):
void OnEnable()
{
EventManager.StartListening("stopStagione", StopStagione);
}
void OnDisable()
{
EventManager.StopListening("stopStagione", StopStagione);
}
void StopStagione(Dictionary<string, object> message)
{
var amount = (double)message["kI"];
kI = amount;
}
public override void RatesOfChange(double[] x, double[] xdot, double t)
{
setup = GameObject.FindGameObjectWithTag("Setup").GetComponent<SetupNew>();
treeInfo = setup.StaticGeneticInfo;
xdot[0] = alpha * x[0] * (1 - (x[0] / x[1])); // lunghezza dL/dt
xdot[1] = 1 - (setup.Manager.TotalLenght() / maxTreeHeight) - 0.2 * (x[2] / iMax); // Lmax
xdot[2] = c * (alpha * x[0] * (1-(x[0]/x[1]))) - kI * x[2]; // Inibitore dI/dt
}
Now, the event is triggered when annualInib is >= 0.95 * theIntegrator.IMax (I’ve checked this with a code break in debug mode) but the kI value in the last code block does not change. Also, the event is constantly triggered because the if-statement is always true when annualInib is >= 0.95 * theIntegrator.IMax.
So, I would like to trigger the event ONCE when annualInib reaches the value of 0.95 * theIntegrator.IMax and change the kI value until another event happens and changes back the value of kI.
How can I do this?
Thank you!