- Home /
Cycling through a List with constantly changing element count. Running into problems D:
Hi,
I've basically got this little script that is supposed to cycle through enemies whenever I press the shift key. It does this, but since the List used to store the enemies keeps changing in size rather fast.
A simple counter runs into index out of range errors, seemingly because when the list would be filled like this: element 0=A, 1=B, 2=C And have enemy C selected, enemy A can suddenly drop out of the list.
Making the list count 2, while I'm trying to select the third, now non existing element. I believe this is the reason why I keep getting these errors, but I'll post a snippet anyway.
function switchLockOnTarget()
{
if(Input.GetKeyDown(KeyCode.LeftShift))
{
if(curLockOn+1>=lockOnTargets.Count)
{
curLockOn = 0;
}
else if(curLockOn+1<=lockOnTargets.Count)
{
curLockOn = curLockOn+1;
}
}
}
Am I missing something simple here, or do I need to consider using different methods of cycling through the list?
Thanks in advance,
~Nick
Answer by Statement · Mar 11, 2013 at 02:24 PM
If you have an index to an item in a list, it would make sense to signal when you modify that list.
In the scenario where an item was removed from the list, any indices that reference a greater index should be decremented by one to maintain the correct index.
Perhaps something like this? There may be typos, I just wrote some code without checking that it compiles.
function RemoveItem(index : int) {
lockOnTargets.RemoveAt(index);
if (curLockOn == index) {
// The target was lost, what should we do now?
}
else if (index < curLockOn) {
// Adjust for items removed "below" us.
curLockOn--;
}
}
Hmm...so, if I'm reading this right, I'd use the RemoveItem function with the index being the number of whatever enemy was just lost to remove the enemy from the list, right? Then check if the target was the one that moved away by comparing it to index. if it isn't, and the index is lower than current target, then we take one from the current target. I think I get it, now that I've written it all out...haha! I'm gonna try this and see if that did the trick.
Edit: Unless I'm getting the wrong idea of what your function does, I think it won't work. still getting the errors. I'm a bit confused...x]
Or, ins$$anonymous$$d of relying on the actual index, keep a reference to the object in the list ins$$anonymous$$d. That way it doesn't matter if the indices change. Then you can use list.IndexOf(myTarget) if you need to find the index for any reason, for example, when you want to move to the next one. If you list becomes very large, then IndexOf could incur some performance overhead since it has to go through each item in the list.
Answer by Bunny83 · Mar 11, 2013 at 02:34 PM
I would suggest to use a LinkedList instead and hold a reference to the node object that is currently selected. That way the order / count can change without breaking the reference to the "next" item. Of course if the payload object (your gameobject) gets destroyed you should select the next / prev element.
I've never tried this myself, but i think it should work.
Unfortunately the LinkedListNode loses it's Next and Previous references when it's been removed from the list, so if the current object is being destroyed / removed you have to find a new one, but i think that's ok since it's no longer part of your cycle.
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Why Is TextMesh Off by One ??? 0 Answers
cycle trhu an Array of gameobjects? 1 Answer
Arguement out of range exception on a lists index 3 Answers
List of type Button has size set to zero at runtime 0 Answers