private object[] GetNodeConstructorParameters(BehaviorTree tree, AbstractActor unit, out Type[] parameterTypes)
        {
            var parameters = new List <object> {
                Name, tree, unit
            };
            var parameterTypeList = new List <Type> {
                typeof(string), typeof(BehaviorTree), typeof(AbstractActor)
            };

            if (ExtraParameters == null || ExtraParameters.Count == 0)
            {
                parameterTypes = parameterTypeList.ToArray();
                return(parameters.ToArray());
            }

            var extraParameterInfo = NodeUtil.GetConstructorExtraParameterInfo(TypeName);

            parameterTypeList.AddRange(extraParameterInfo.Select(parameterInfo => parameterInfo.ParameterType));
            parameters.AddRange(extraParameterInfo.Select(parameterInfo => ExtraParameters[parameterInfo.Name]));

            // for some reason unity/newtonsoft json doesn't seem to like converting
            // string -> enum while the tests seem to work just fine
            // this causes hang on mission load without any sort of exception or anything
            for (var i = 0; i < parameterTypeList.Count; i++)
            {
                var parameterType = parameterTypeList[i];
                if (parameterType.IsEnum && parameters[i] is string parameter)
                {
                    parameters[i] = Enum.Parse(parameterTypeList[i], parameter);
                }
            }

            parameterTypes = parameterTypeList.ToArray();
            return(parameters.ToArray());
        }
        public static BehaviorNodeDef FromNode(BehaviorNode node)
        {
            var rep = new BehaviorNodeDef();

            rep.Name     = node.GetName();
            rep.TypeName = node.GetType().ToString();

            switch (node)
            {
            case CompositeBehaviorNode composite:
                rep.Children = new List <BehaviorNodeDef>();
                foreach (var child in composite.Children)
                {
                    rep.Children.Add(FromNode(child));
                }
                break;

            case DecoratorBehaviorNode decorator:
                rep.Children = new List <BehaviorNodeDef> {
                    FromNode(decorator.ChildNode)
                };
                break;

            default:
                rep.Children = null;
                break;
            }

            var extraParameterInfo = NodeUtil.GetConstructorExtraParameterInfo(node.GetType());

            if (extraParameterInfo == null || extraParameterInfo.Length == 0)
            {
                return(rep);
            }

            rep.ExtraParameters = new Dictionary <string, object>();
            foreach (var parameterInfo in extraParameterInfo)
            {
                var value = NodeUtil.GetParameterValueByType(node, parameterInfo.ParameterType);
                rep.ExtraParameters.Add(parameterInfo.Name, value);
            }

            return(rep);
        }