Forums › 💬 NodeCanvas › ⚙️ Support › Blackboard Variable changed condition
I’m trying to create a condition task that returns true when a BB variable changes. Everything works except OnDisabled gets called after the transition in a FSM. So in this case where should I unsubscribe from the OnValueChanged event to clean up the event listener?
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
namespace Game.Tasks.Conditions { [Name("On Variable Changed")] [Category("✫ Blackboard")] public class BBVariableChanged : ConditionTask { [BlackboardOnly] public BBParameter<object> BBVar; protected override string info { get { return BBVar + " Changed."; } } protected override string OnInit() { if(BBVar != null) { BBVar.varRef.onValueChanged += OnValueChanged; YieldReturn(true); } else{ Debug.LogWarning("Blackboard Variable not set."); } return base.OnInit(); } protected override bool OnCheck() { return false; } protected override void OnDisable() { if (BBVar != null) { BBVar.varRef.onValueChanged -= OnValueChanged; } base.OnDisable(); } private void OnValueChanged(string arg1, object arg2) { YieldReturn(true); } } } |
Hello and sorry for the late reply.
I have modified your code to work as I expect you want it to:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
using NodeCanvas.Framework; using ParadoxNotion.Design; using UnityEngine; namespace Game.Tasks.Conditions { [Name("On Variable Changed")] [Category("✫ Blackboard")] public class BBVariableChanged : ConditionTask { [BlackboardOnly] public BBParameter<object> BBVar; protected override string info{ get { return BBVar + " Changed."; } } protected override string OnInit(){ if (BBVar.isNone){ return "Blackboard Variable not set."; } return null; } protected override void OnEnable(){ BBVar.varRef.onValueChanged += OnValueChanged; } protected override void OnDisable(){ BBVar.varRef.onValueChanged -= OnValueChanged; } protected override bool OnCheck(){ return false; } private void OnValueChanged(string arg1, object arg2){ YieldReturn(true); } } } |
Some notes:
– Use OnInit only for initialization similar to Unity’s Awake.
– Use OnEnable and OnDisable to subscribe and unsubscribe.
– You don’t have to call base implementation of methods.
– A BBParameter will never be null. Use .isNone to determine if the front-end user has selected a variable or not.
Let me know if that works for you.
Thanks!
Thanks that works now for normal conditions but I did notice one issue. When the condition is part of a Concurrent node OnEnable is not called but OnInit is. Thus the condition does not work in Concurrent nodes because the event never gets setup.
Not sure if that is a bug or working as intended?
Hello and sorry for the late reply.
You are correct. This is actually a bug in the Concurrent Node.
To fix this, please open up ConcurrentState.cs file and:
1) In the OnEnter Method, add this line of code above everything else:
conditionList.Enable(graphAgent, graphBlackboard);
2) In the OnExit method, add this line of code first as well:
conditionList.Disable();
Thanks for the report!
