1

Trying to using Array.Copy in the Unity Monodevelop environment, specifically what I'm trying to do is move a value from the first slot of the array into a holder variable, then move every value in the array forward one slot, then move the value from the holder variable back into the Array in the last slot. My relevant code is as follows:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class TurnController : MonoBehaviour {

//Array will hold all units (Being that they all have the EidolonClass script attached), then will be sorted by Speed, descending
private EidolonClass[] AllUnitArray;

...

void Awake(){
   //Find anything with the EidolonClass and then add it to the Array
   AllUnitArray = FindObjectsOfType (typeof(EidolonClass)) as EidolonClass[];
   //Sort the array by speed, descending (Highest speed listed first)
   Array.Sort (AllUnitArray, delegate(EidolonClass one, EidolonClass two) {
          return two.Speed.CompareTo(one.Speed);
          });
}

void pushArray(){
        EidolonClass store = AllUnitArray [0];
        for(int i=1;i<=AllUnitArray.Length;i++){
            Array.Copy (AllUnitArray, i, AllUnitArray, i-1, AllUnitArray.Length-1);
        }
        AllUnitArray [AllUnitArray.Length] = store;
        for(int i=0;i<=AllUnitArray.Length;i++) {
            Debug.Log (AllUnitArray[i].name.ToString ());
        }
    }

void Update () {
        if (Input.GetKeyDown (KeyCode.K)) {
            pushArray ();
        }
    }

This code compiles in Monodevelop, but when I try to run this section of my script, it returns the following error:

ArgumentException: length

System.Array.Copy (System.Array sourceArray, Int32 sourceIndex, System.Array destinationArray, Int32 destinationIndex, Int32 length) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Array.cs:971) TurnController.pushArray () (at Assets/Scripts/Battle Scripts/TurnController.cs:54) TurnController.Update () (at Assets/Scripts/Battle Scripts/TurnController.cs:37)

Community
  • 1
  • 1
Quelandoris
  • 13
  • 1
  • 6
  • well , you change the start offset but always use the same length. Thats not going to work. PS why the loop, surely you only need to do 1 copy – pm100 Mar 06 '17 at 22:58
  • Essentially this is a turn manager. Whatever is in the 0th slot is on its current turn, when that turn in over (or for testing purposes, when I hit K) i need the entire array to shift so that everything stays in order and it continues to work when the next turn is over – Quelandoris Mar 06 '17 at 23:00
  • Basically, you want to move/shift every object in the array up by one. Then the first object should now be in the last index? – Programmer Mar 06 '17 at 23:02
  • Essentially, yeah. – Quelandoris Mar 06 '17 at 23:03
  • Check the `shiftUp()` function from the answer in the duplicated question. That's exactly what you are looking for and even the title says it all. – Programmer Mar 06 '17 at 23:10

1 Answers1

1

Your exception occurs because you are trying to copy the same length multiple times, but with new starting offsets each time. To shift the contents of the array, a single call to Array.Copy() would suffice.

Something like this:

void pushArray(){
    EidolonClass store = AllUnitArray [0];

    Array.Copy (AllUnitArray, 1, AllUnitArray, 0, AllUnitArray.Length - 1);
    AllUnitArray[AllUnitArray.Length - 1] = store;

    for(int i=0;i<=AllUnitArray.Length;i++) {
        Debug.Log (AllUnitArray[i].name.ToString ());
    }
}

That said, an array doesn't seem like the best data structure here, if you want to be able to "shift" the contents. If you were using a Queue<EidolonClass> object, then you could just Dequeue() the first element and then Enqueue() the same element to put it at the back of the list.

Personally, I wouldn't bother with either. Instead of trying to shuffle your data around, just keep an index of which element's turn is current. Increment the index to move to the next element's turn. If you reach the end of the array (i.e. the index value is equal to AllUnitArray.Length), then set the index back to 0.

Actually, the Queue<T> class does exactly that internally anyway. So if you like the semantics of the Queue<T> class, it's about the same implementation-wise.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • Since I'm on a time crunch, ill probably go with your second suggestion to just use an index. Out of curiousity, How would I use that system or the Queue system to allow for advanced turn order, i.e. if a unit has more than twice the speed of the next highest-speed unit, they get two turns in a row? – Quelandoris Mar 06 '17 at 23:11