Hammy
Hammy

Reputation: 9

Index was out of range. Must be non-negative and less than the size of the collection. C#

im trying to make a script for automated, dynamic adjustment of thrusters to maintain the speed of a vehicle.

in case u want to know its for a game^^

well anyway it keeps getting me that index was out of range error.

Heres my Code i added comments to make it more clearly

List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();

string ThrusterControl = "Thrusters.Forward";    //the name of my thrusters.
string CruiseControl = "AI.Computer";            //The name of the block running this code.
double setSpeed=0.250;                           //my desired speed (units/tick).  
double maxSpeed=3.000;                           //This script disengages thruster overrides while im are above this speed.
double checkSpeed=0.75;                          //Determines the acceptable speed range.  
double decelerationRate=0.9;                     //Thrust override reduction factor
float speedBoost=500;                            //Gives a boost when im not moving
float minThrust=125;                             //Minimum legal value of thrust override.
double x0,dx; 
double y0,dy; 
double z0,dz; 
double speed; 
float newThrust;

void Main(){

//Determine ship speed. 

GridTerminalSystem.SearchBlocksOfName(CruiseControl,blocks);
double x = Math.Round(blocks[0].GetPosition().GetDim(0),3);
double y = Math.Round(blocks[0].GetPosition().GetDim(1),3);
double z = Math.Round(blocks[0].GetPosition().GetDim(2),3);
dx=x-x0;dy=y-y0;dz=z-z0;x0=x;y0=y;z0=z;
    speed=Math.Round(Math.Sqrt(dx*dx+dy*dy+dz*dz),5);
        blocks[0].SetCustomName(CruiseControl+":"+"\n"+"speed (units/tick) "+speed );

//Increase thrust override if im going too slow.

if(speed < setSpeed * checkSpeed){
GridTerminalSystem.SearchBlocksOfName(ThrusterControl, blocks);
    for(int i=0; i < blocks.Count;){
        blocks[0].GetActionWithName("IncreaseOverride").Apply(blocks[0]);
        i++;}

//Give an extra thrust boost if you're im not moving at all.

if(speed < setSpeed * 0.05){
    newThrust = (float)Math.Round(blocks[0].GetValueFloat("Override") + speedBoost,4);
    for(int i=0; i < blocks.Count;){
        blocks[i].SetValueFloat("Override", newThrust);
        i++;}
    }
}

//Slowly reduces thrust override if im going too fast.

if(speed > setSpeed / checkSpeed){
GridTerminalSystem.SearchBlocksOfName(ThrusterControl, blocks);
newThrust = (float)Math.Round(blocks[0].GetValueFloat("Override") * decelerationRate, 4);
if( newThrust > minThrust){    //Prevents this script from disabling the thruster override.
    for(int i=0; i < blocks.Count;){
        blocks[i].SetValueFloat("Override", newThrust); 
        i++;}
    }

//Reset thruster overrides if moving too fast. Allows inertial dampers to regain control of vehicle.

if(speed > maxSpeed){
    for(int i=0; i < blocks.Count;){
        blocks[i].SetValueFloat("Override", 0);
        i++;}
    }
}

}

can someone correct my code please?

Upvotes: 0

Views: 150

Answers (1)

C.Evenhuis
C.Evenhuis

Reputation: 26446

Instead of having someone correct your code, wouldn't it be nice to understand exactly what's going on?

This exception is quite easy to debug. Visual Studio will stop execution where it occurs, and highlight the exact line. While this line is highlighted, you can mouse-over your variables and see their values to:

  • Inspect the collection, and the number of items in it
  • Inspect the variable that holds the index which is causing the problem

Debugger

The index variable will then either be less than 0 or greater or equal to the number of items in the collection.

With that information, you might be able to solve the issue yourself, but if not, you'll be able to ask a totally different question on SO.

EDIT:

If you're unable to debug this properly, you can always do a range check yourself, ie:

public void MyFunction()
{
    for (int i = ...)
    {
        if (i < 0 || i >= blocks.Count)
        {
            System.IO.File.AppendAllText(@"error.log", "Error in MyFunction(), i = " + i + ", blocks.Count = " + blocks.Count);
        }

        blocks[i].SetValue(...);
    }
}

It takes alot more time, but it will at least give you insight in what's going on.

Upvotes: 2

Related Questions