Forums › 💬 NodeCanvas › ⚙️ Support › Custom foreach iterator
I’ve written custom iterator that goes through a list, but for some reason the variable is not being assigned. Wonder what am I doing wrong. I have check for the chosen variable value against Null – and it is null for some reason. So the _ability var is all good, but _ability.value is null in other nodes. I’m sure that the actual list is fine, as I have a fallback that just randomly picks ability from the same list. It’s this temp variable “_ability” that has its value as null in nodes that are children of my custom foreach node.
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
#if UNITY_EDITOR using UnityEditor; #endif using UnityEngine; using System.Collections; using System.Collections.Generic; using NodeCanvas.Variables; namespace NodeCanvas.BehaviourTrees{ [AddComponentMenu("")] [Name("Ability Iterate")] [Category("Eco")] [Description("Iterate a game object list and execute the child node for each object in the list. Keeps iterating until the Termination Condition is met or the whole list is iterated and return the child node status")] [Icon("List")] ///Iterate a GameObject list public class NCEcoAbilityIterator : BTDecorator{ [BlackboardOnly] public BBEcoNPCAbilityList list; [BlackboardOnly] public BBEcoNPCAbility current; public BBInt maxIteration; public enum TerminationConditions {FirstSuccess, FirstFailure, None} public TerminationConditions terminationCondition = TerminationConditions.None; public bool resetIndex = true; private int currentIndex; protected override Status OnExecute(Component agent, Blackboard blackboard){ if (!decoratedConnection) return Status.Resting; if (list.value == null || list.value.Count == 0) return Status.Failure; current.value = list.value[currentIndex]; status = decoratedConnection.Execute(agent, blackboard); if (status == Status.Success && terminationCondition == TerminationConditions.FirstSuccess) return Status.Success; if (status == Status.Failure && terminationCondition == TerminationConditions.FirstFailure) return Status.Failure; if (status != Status.Running){ if (currentIndex == list.value.Count - 1 || currentIndex == maxIteration.value - 1) return status; decoratedConnection.ResetConnection(); currentIndex ++; return Status.Running; } return status; } protected override void OnReset(){ if (resetIndex || currentIndex == list.value.Count - 1 || currentIndex == maxIteration.value - 1) currentIndex = 0; } //////////////////////////////////////// ///////////GUI AND EDITOR STUFF///////// //////////////////////////////////////// #if UNITY_EDITOR protected override void OnNodeGUI(){ GUILayout.Label("For Each t'<b>$" + current.dataName + "</b>'nIn ttt'<b>$" + list.dataName + "</b>'"); //GUILayout.Label(""); if (terminationCondition != TerminationConditions.None) GUILayout.Label("Exit on " + terminationCondition.ToString()); if (Application.isPlaying) GUILayout.Label("Index: " + currentIndex.ToString() + " / " + (list.value != null && list.value.Count != 0? (list.value.Count -1).ToString() : "?") ); } #endif } } |
Everything seems ok without seeing more, but I am sure the author will respond soon enough with some info, I have seen some odd behaviour around custom iterators when using within cloned instances within prefabs an prefabbed trees but currently it all works.
Hey,
Have you checked in the blackboard that the List elements within are not null? Could it be that they are null for some reason and as such the iterator do work, but current is null because elements are null?
By the way if the ONLY difference in your iterator is that it iterates a different list type than game bject, then you can use the attached Iterator Version2 which is possible to iterate any type of list 🙂
Let me know about you issue in either case.
Thanks for that!