NodeCanvas Forums › Support › C# Event driven FSM no longer works?
My NC1 implementation used C# events to drive state changes. This seems to be broken or changed in the latest version of NC.
If I create an empty scene with only a cube, attach the following script and then implement the linked FSM on the cube. I get the following error as soon as a State is reached that contains a C# Event condition.
InvalidCastException: Cannot cast from source type to destination type.
System.Reflection.EventInfo.AddEventFrame[TestScript,EmptyEventHandler] (System.Reflection.AddEvent`2 addEvent, System.Object obj, System.Object dele) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/EventInfo.cs:174)
System.Reflection.EventInfo.AddEventHandler (System.Object target, System.Delegate handler) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Reflection/EventInfo.cs:100)
NodeCanvas.Tasks.Conditions.CheckCSharpEvent.OnInit () (at Assets/NodeCanvas/Tasks/Conditions/ScriptControl/CheckCSharpEvent.cs:45)
NodeCanvas.Framework.Task.Initialize (UnityEngine.Component newAgent, System.Type newType) (at Assets/NodeCanvas/Framework/Tasks/Task.cs:371)
NodeCanvas.Framework.Task.Set (UnityEngine.Component newAgent, IBlackboard newBB) (at Assets/NodeCanvas/Framework/Tasks/Task.cs:340)
NodeCanvas.Framework.ConditionTask.CheckCondition (UnityEngine.Component agent, IBlackboard blackboard) (at Assets/NodeCanvas/Framework/Tasks/ConditionTask.cs:45)
NodeCanvas.StateMachines.FSMState.CheckTransitions () (at Assets/NodeCanvas/Modules/StateMachines/FSMState.cs:123)
NodeCanvas.StateMachines.FSMState.Update () (at Assets/NodeCanvas/Modules/StateMachines/FSMState.cs:103)
NodeCanvas.StateMachines.FSM.OnGraphUpdate () (at Assets/NodeCanvas/Modules/StateMachines/FSM.cs:70)
ParadoxNotion.Services.MonoManager.Update () (at Assets/NodeCanvas/_ParadoxNotion (shared)/Services/MonoManager.cs:51)
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 |
using UnityEngine; using System.Collections; public class TestScript : MonoBehaviour { public delegate void EmptyEventHandler(); public event EmptyEventHandler UnDocked; public event EmptyEventHandler Docked; public event EmptyEventHandler StartUp; public IEnumerator Undock() { yield return new WaitForSeconds(2f); if (UnDocked != null) UnDocked(); } public IEnumerator Dock() { yield return new WaitForSeconds(2); if (Docked != null) Docked(); } } |
It appears to be failing to attach to the event.
Any ideas?
Hehe… Kinda funny that you don’t allow FSM attachments that are generated by your own software. 😉
Here is the raw text from the FSM export.
{
“version”: 2.0,
“type”: “NodeCanvas.StateMachines.FSM”,
“name”: “FSM”,
“comments”: “”,
“translation”: {
“x”: -5000.0,
“y”: -5000.0
},
“nodes”: [
{
“_actionList”: {
“executionMode”: “ActionsRunInParallel”,
“actions”: [
{
“waitTime”: {
“_value”: 5.0,
“_name”: null
},
“finishStatus”: “Success”,
“_isActive”: true,
“overrideAgent”: null,
“$type”: “NodeCanvas.Tasks.Actions.Wait”
}
],
“_isActive”: true,
“overrideAgent”: null
},
“_repeatStateActions”: false,
“_transitionEvaluation”: “CheckContinuously”,
“_collapsed”: false,
“_position”: {
“x”: 5430.0,
“y”: 5040.0
},
“_name”: null,
“_tag”: null,
“_comment”: null,
“_isBreakpoint”: false,
“$type”: “NodeCanvas.StateMachines.ActionState”,
“$id”: “1”
},
{
“_actionList”: {
“executionMode”: “ActionsRunInParallel”,
“actions”: [
{
“functionWrapper”: {
“result”: {
“_value”: null,
“_name”: “”
},
“_targetMethod”: {
“_baseInfo”: “TestScript|Dock”,
“_paramsInfo”: “”
},
“$type”: “NodeCanvas.Framework.Internal.ReflectedFunction1[[System.Collections.IEnumerator, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]”
1[[System.Collections.IEnumerator, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]”
},
“_isActive”: true,
“overrideAgent”: null,
“$type”: “NodeCanvas.Tasks.Actions.ExecuteFunction”
}
],
“_isActive”: true,
“overrideAgent”: null
},
“_repeatStateActions”: false,
“_transitionEvaluation”: “CheckContinuously”,
“_collapsed”: false,
“_position”: {
“x”: 5580.0,
“y”: 5220.0
},
“_name”: null,
“_tag”: null,
“_comment”: null,
“_isBreakpoint”: false,
“$type”: “NodeCanvas.StateMachines.ActionState”,
“$id”: “5”
},
{
“_actionList”: {
“executionMode”: “ActionsRunInParallel”,
“actions”: [
{
“functionWrapper”: {
“result”: {
“_value”: null,
“_name”: “”
},
“_targetMethod”: {
“_baseInfo”: “TestScript|Undock”,
“_paramsInfo”: “”
},
“$type”: “NodeCanvas.Framework.Internal.ReflectedFunction
},
“_isActive”: true,
“overrideAgent”: null,
“$type”: “NodeCanvas.Tasks.Actions.ExecuteFunction”
}
],
“_isActive”: true,
“overrideAgent”: null
},
“_repeatStateActions”: false,
“_transitionEvaluation”: “CheckContinuously”,
“_collapsed”: false,
“_position”: {
“x”: 5835.0,
“y”: 5370.0
},
“_name”: “sdfsdf”,
“_tag”: null,
“_comment”: null,
“_isBreakpoint”: false,
“$type”: “NodeCanvas.StateMachines.ActionState”,
“$id”: “11”
}
],
“connections”: [
{
“_condition”: null,
“_infoExpanded”: true,
“_sourceNode”: {
“$ref”: “1”
},
“_targetNode”: {
“$ref”: “5”
},
“_isActive”: true,
“$type”: “NodeCanvas.StateMachines.FSMConnection”
},
{
“_condition”: {
“targetType”: “TestScript”,
“eventName”: “Docked”,
“_invert”: false,
“_isActive”: true,
“overrideAgent”: null,
“$type”: “NodeCanvas.Tasks.Conditions.CheckCSharpEvent”
},
“_infoExpanded”: true,
“_sourceNode”: {
“$ref”: “5”
},
“_targetNode”: {
“$ref”: “11”
},
“_isActive”: true,
“$type”: “NodeCanvas.StateMachines.FSMConnection”
},
{
“_condition”: {
“targetType”: “TestScript”,
“eventName”: “UnDocked”,
“_invert”: false,
“_isActive”: true,
“overrideAgent”: null,
“$type”: “NodeCanvas.Tasks.Conditions.CheckCSharpEvent”
},
“_infoExpanded”: true,
“_sourceNode”: {
“$ref”: “11”
},
“_targetNode”: {
“$ref”: “5”
},
“_isActive”: true,
“$type”: “NodeCanvas.StateMachines.FSMConnection”
}
],
“primeNode”: {
“$ref”: “1”
},
“canvasGroups”: null,
“localBlackboard”: {
“_name”: “Local Blackboard”,
“_variables”: [],
“$type”: “NodeCanvas.Framework.Internal.BlackboardSource”
}
}
Hello,
Yeah, I will have to allow attachements of those types 🙂
So, the new ‘CheckCSharp’ condition supports events of System.Action delegate, since in any case no parameters are supported there:
1 2 3 |
public event System.Action StartUp; |
If there is a reason you want to use custom delegates, I can provide you with a modified condition.
Let me know.
PS: I will have to remove the possibility to select any delegate type
Join us on Discord: https://discord.gg/97q2Rjh
Thanks. That resolved the error. I’m still having an issue where executing a Coroutine from an action isn’t behaving in the same way. Did something change in how the enumerated results are handled?
Hello,
I have replied to the other thread about the coroutine error and fix 🙂
Thanks
Join us on Discord: https://discord.gg/97q2Rjh