public override void RegisterPort() { register.onExecute = () => { if (target.isAssigned) { object val = target.Get(); if (val == null) { val = new MemberData.Event(target.CreateRuntimeEvent(), null); } if (val is MemberData.Event) { MemberData.Event e = val as MemberData.Event; if (e.eventInfo != null) { if (m_Delegate == null) { if (e.eventInfo is RuntimeEvent) { var returnType = target.type.GetMethod("Invoke").ReturnType; m_Delegate = new MemberData.EventCallback((obj => { if (owner == null) { return(null); } if (obj != null && parameters.Count == obj.Length) { for (int i = 0; i < obj.Length; i++) { parameters[i] = obj[i]; } } if (returnType == typeof(void)) { body.InvokeFlow(); return(null); } else { Node n; WaitUntil w; if (!body.ActivateFlowNode(out n, out w)) { throw new uNodeException("Coroutine aren't supported by EventHook node in runtime.", this); } if (n == null) { throw new uNodeException("No return value", this); } JumpStatement js = n.GetJumpState(); if (js == null || js.jumpType != JumpStatementType.Return || !(js.from is NodeReturn)) { throw new uNodeException("No return value", this); } return((js.from as NodeReturn).GetReturnValue()); } })); } else { var method = e.eventInfo.EventHandlerType.GetMethod("Invoke"); var type = method.ReturnType; if (type == typeof(void)) { m_Delegate = CustomDelegate.CreateActionDelegate((obj) => { if (owner == null) { return; } if (obj != null && parameters.Count == obj.Length) { for (int i = 0; i < obj.Length; i++) { parameters[i] = obj[i]; } } body.InvokeFlow(); }, method.GetParameters().Select(i => i.ParameterType).ToArray()); } else { var types = method.GetParameters().Select(i => i.ParameterType).ToList(); types.Add(type); m_Delegate = CustomDelegate.CreateFuncDelegate((obj) => { if (owner == null) { return(null); } if (obj != null && parameters.Count == obj.Length) { for (int i = 0; i < obj.Length; i++) { parameters[i] = obj[i]; } } Node n; WaitUntil w; if (!body.ActivateFlowNode(out n, out w)) { throw new uNodeException("Coroutine aren't supported by EventHook node in runtime.", this); } if (n == null) { throw new uNodeException("No return value", this); } JumpStatement js = n.GetJumpState(); if (js == null || js.jumpType != JumpStatementType.Return || !(js.from is NodeReturn)) { throw new uNodeException("No return value", this); } return((js.from as NodeReturn).GetReturnValue()); }, types.ToArray()); } m_Delegate = ReflectionUtils.ConvertDelegate(m_Delegate, e.eventInfo.EventHandlerType); } } e.eventInfo.AddEventHandler(e.instance, m_Delegate); } } else if (val is UnityEventBase) { var method = val.GetType().GetMethod("AddListener"); if (m_Delegate == null) { var param = method.GetParameters()[0].ParameterType; var gType = param.GetGenericArguments(); m_Delegate = CustomDelegate.CreateActionDelegate((obj) => { if (owner == null) { return; } if (obj != null && parameters.Count == obj.Length) { for (int i = 0; i < obj.Length; i++) { parameters[i] = obj[i]; } } body.InvokeFlow(); }, gType); m_Delegate = System.Delegate.CreateDelegate(param, m_Delegate.Target, m_Delegate.Method); } method.InvokeOptimized(val, new object[] { m_Delegate }); } else { if (val == null) { throw new uNodeException("The target event is null", this); } throw new uNodeException("Invalid target value: " + val, this); } } }; unregister.onExecute = () => { if (m_Delegate != null && target.isAssigned) { object val = target.Get(); if (val is MemberData.Event) { MemberData.Event e = val as MemberData.Event; if (e.eventInfo != null) { e.eventInfo.RemoveEventHandler(e.instance, m_Delegate); } } else if (val is UnityEventBase) { var method = val.GetType().GetMethod("RemoveListener"); method.InvokeOptimized(val, new object[] { m_Delegate }); } } }; if (CodeGenerator.isGenerating) { CodeGenerator.RegisterFlowNode(this); register.codeGeneration = () => { if (target.type.IsCastableTo(typeof(UnityEventBase))) { return(target.ParseValue().AddFunction("AddListener", GenerateEventCodes()).AddSemicolon()); } return(CodeGenerator.GenerateSetCode(target, GenerateEventCodes(), SetType.Add, target.type)); }; unregister.codeGeneration = () => { if (target.type.IsCastableTo(typeof(UnityEventBase))) { return(target.ParseValue().AddFunction("RemoveListener", GenerateEventCodes()).AddSemicolon()); } return(CodeGenerator.GenerateSetCode(target, GenerateEventCodes(), SetType.Subtract, target.type)); }; } }