Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Nk.Andrei · Jul 26, 2013 at 06:04 PM · javascripterrorarrayindex

NullReferenceException array

I have a serious problem with this segment of code.....the last part of it when I index through the array it always gives me NullReferenceException but I know the list isnt empty and my Cel class has a position and an h cost to it.

 //testt.js
 
 #pragma strict
  
 class testt extends MonoBehaviour //// the representation of a GridCell made from Cells
 {
     var agentTransform : Transform;
     var enemyTransform : Transform;
     var parentCell     : Cel;
  
     var lowestCost     : float;
  
     var list : List.<Cel> = new List.<Cel>();
  
  
     var cube    : Transform;
     var hit      : RaycastHit;
     var distance   : int = 10;
     var color       : Color;
  
     var v         : int ;//number of cells
     var i         : int;
     var x         : int;
     var c         : int;
  
  
     var cellSize   : int ;//cell size
     var cellSizeX  : int;
     var cellSizeZ  : int;
  
     var scale       : int;
     var cells      : Cel[,];//2d array ------ that ---- accepts only cells
     var cel      : Cel;
  
     var currentPos        : Vector3;
     var topLeftCorner  : Vector3;
  
  
  
  
  
  
     function Start()
     {
        lowestCost = Mathf.Infinity;
        v = 6;
        cellSize = 4;
  
  
        cel.obj    = agentTransform;
        cel.enemy  = enemyTransform;
        cel.color  = Color.red;
        scale = 2;
        topLeftCorner =Vector3 (transform.position.x-transform.localScale.x/scale ,transform.position.y  ,transform.position.z-transform.localScale.z/scale);
     }
  
     function Update()
     {  
  
  
        cells = new Cel[v,v];///the size of the 2d array
  
        cellSizeX = transform.localScale.x / cellSize;//width
        cellSizeZ = transform.localScale.z / cellSize;//height
  
  
        for(i = 0 ; i < v ; i ++)
        {
          for(x = 0 ; x < v ; x ++)
          {
  
           ////THE CURRENT POSITION AND TYPE OF CELLS////
           //print(x);
           currentPos = topLeftCorner + Vector3(i*cellSizeX,0,x*cellSizeZ); ////current position of the cell in i,x coordonates
           cells[i,x] = cel;////each of cells of coordonates [1,1] or cells[1,2] etc will equal one cell
           cells[i,x].celPos =currentPos;
           ////THE CURRENT POSITION AND TYPE OF CELLS////
  
  
  
  
           ////not good
  
           parentCell = cells[i,x].currentCellParent;//parrentCell = the first cell in the list
  
           ////not good
  
  
  
           //if(list != null)
           ///{
           //  list.Clear();
           //}
  
  
  
  
  
           ////ADD NEIGHBOUR CELLS////
  
           if(i+1 < v && x+1 < v)
           {
               if(!list.Contains(cells[i+1,x+1]))////this is better////but still not good////only if list contains the i+1,x+1 if not then add
               {
                  list.Add(cells[i+1,x+1]);////this is better////but still not good////only if list contains the i+1,x+1 if not then add
               }
           }
           if(i-1 > 0 && x-1 > 0)
  
           {
               if(!list.Contains(cells[i-1,x-1]))
               {
                  list.Add(cells[i-1,x-1]);
               }
           }
           if(i-1 > 0 && x+1 < v)
  
           {
               if(!list.Contains(cells[i-1,x+1]))
               {
                  list.Add(cells[i-1,x+1]);
               }
           }
           if(i+1 < v && x-1 > 0)
  
           {
               if(!list.Contains(cells[i+1,x-1]))
               {
                  list.Add(cells[i+1,x-1]);
               }
           }
           if(x+1 < v)
  
           {
               if(!list.Contains(cells[i,x+1]))
               {
                  list.Add(cells[i,x+1]);
               }
           }
           if(x-1 > 0)
  
           {
               if(!list.Contains(cells[i,x-1]))
               {
                  list.Add(cells[i,x-1]);
               }
           }
           if(i+1 < v)
  
           {
               if(!list.Contains(cells[i+1,x]))
               {
                  list.Add(cells[i+1,x]);
               }
           }
           if(i-1 > 0)
  
           {
               if(!list.Contains(cells[i-1,x]))
               {
                  list.Add(cells[i-1,x]);
               }
           }
           ////ADD NEIGHBOUR CELLS////
  
  
           //print(list.Count);
           ////THE LOWEST COST////
           for(c = 0 ; c < list.Count ; c++)
           {
               if(list != null)
               {
                  //list[c] = cells[i,x];////????////
                  //print("abba");
                  Instantiate(cube,list[c].celPos,transform.rotation);
                  if(list[c].h < lowestCost)
                  {
                    lowestCost = list[c].h;
                  }
               }
           }
           ////THE LOWEST COST////
  
  
           ////ADD THE LOWEST CELL TO LIST////
           if(agentTransform != null)
           {
               if(cells[i,x].h == lowestCost && !agentTransform.GetComponent(pathFind).theOpenList.Contains(cells[i,x]))
               {
                  cells[i,x].currentCellParent = cells[i,x];////not good
                  agentTransform.GetComponent(pathFind).theOpenList.Add(cells[i,x]);
               }
           }
           ////ADD THE LOWEST CELL TO LIST////
  
  
  
           ////ADD THE FIRST CELL TO LIST////
           if(Physics.Raycast(cells[i,x].celPos , Vector3.up , hit,distance))
           {
               if(hit.transform.tag == "agent" && hit.transform.GetComponent(pathFind).theOpenList.Count == 0)
               {
                  hit.transform.GetComponent(pathFind).theOpenList.Add(cells[i,x]);
                  Instantiate(cube,cells[i,x].celPos,transform.rotation);
                  print(cells.length);
               }
           }
              Debug.DrawRay(cells[i,x].celPos,Vector3(0,10,0), cells[i,x].color);
           ////ADD THE FIRST CELL TO LIST////
  
          }
        } 
  
     }
 }
 
 


 //Cel.js
 
 #pragma strict
  
 class Cel ////the representation of a Cell
 {
  
     var h : float;
  
     var obj      : Transform;
     var enemy    : Transform;  ////the enemy and its distance
     var distance  : Vector3;   ////the distance from this cell to the enemy
     var celPos       : Vector3;   ////this cells position
     var color    : Color;   ////this cells color
  
     var availible  : boolean = true;
     var inList        : boolean = false;
     var trueT      : boolean = false;
     var road    : boolean = false;
  
     var object : boolean = false;
  
     var currentCellParent : Cel;//////the parent of this cell
  
  
     function Cel (position : Vector3, object : Transform,  enemyPos : Transform, parent : Cel, hCost : float)
     {
        h = hCost;
        celPos          = position;
        obj           = object; //the object(cellunit) from witch we get the object position, distance,color
        enemy           = enemyPos;
        currentCellParent     = parent;  //this is better
  
        if(enemy != null)
        {
          distance = obj.position - enemy.position;
          h        = distance.magnitude * 10;
        } 
     }
  
     function Update()
     {
  
     }
 }
 

The error only appears at runTime and I cant figure out why.....the error always directs me to the part where I try to access the h or position by indexing the list.I really need help.

Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image perchik · Jul 26, 2013 at 06:18 PM 0
Share

When you say it only appears at "runTime" do you mean in builds but not in the editor? or just when you click play?

Can you provide which line number the error refers to?

Also can you provide the code where you initialize cells and list? [also, list is not a good name to use for a list, because often list is a reserved word]

avatar image clunk47 · Jul 26, 2013 at 06:19 PM 0
Share

You need to

 1-Post the whole code if you want us to be able to test it in Unity. 
 
 2-Give the exact error message telling us what line the error is on.
avatar image perchik · Jul 26, 2013 at 07:32 PM 0
Share

Do 2D arrays actually work like this in js var cells : Cel[,]; ?

avatar image perchik · Jul 26, 2013 at 07:39 PM 0
Share

yeah, I just can't find anything online about that syntax in JS

2 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by Peter G · Jul 26, 2013 at 07:57 PM

This is kind of a long explanation. You aren't creating your cells correctly. I'm sorry to say that, but there's no way around it. It looks like you are trying to create one cell then clone it v*v times to create the entire grid. There's nothing wrong with that idea, but you made Cel a reference type (as all classes are). What you are actually doing is creating one Cell. Then creating v*v references to the same cell. Every time you update that cell's position, you are just changing the position of the original cell.

What you need to do is either:

  1. Make cell a value type which it probably should be to begin with. That is your best solution. Just change it to:

      class Cel extends System.ValueType
    
      that way when you clone it, you will actually copy all the information from one instance to the next.
    
    
  2. You can create a new instance of Cel for each square if you want. Then you just can't clone it.

That should almost solve all your problems. You have a second problem also. This is what was actually causing your null reference.

 if(i+1 < v && x+1 < v) {
    if(!list.Contains(cells[i+1,x+1]))////this is better////but still not good////only if list contains the i+1,x+1 if not then add
    {
       list.Add(cells[i+1,x+1]);////this is better////but still not good////only if list contains the i+1,x+1 if not then add
    }
 }

This problems a little harder to see. cells[i+1 , x+1] is probably null on the first frame. You create the whole list of cells, but since Cel is reference type, the whole array initializes to null. Since you're going through and creating the rows in order (the double for loops). cells[i+1 , x+1] won't actually reference anything until you get to it in the loop (which won't be until v+1) iteration later. Hence when you index them later. list[c] is still full of lots of nulls.

I think your best solution is to create the whole grid in Start() and then just do your pathfinding checks in the Update(). It doesn't look like your grid changes much frame to frame so its best to initialize once and be done with it anyway. The other nice thing about using a value type for your Cel is you can't get a null reference.

 class testt extends MonoBehaviour //// the representation of a GridCell made from Cells
 {
     var parentCell     : Cel;
  
     var list : List.<Cel> = new List.<Cel>();
  
     var v         : int ;//number of cells
     var i         : int;
     var x         : int;
     var c         : int;
  
     var cellSize   : int ;//cell size
     var cellSizeX  : int;
     var cellSizeZ  : int;
  
     var scale       : int;
     var cells      : Cel[,];//2d array ------ that ---- accepts only cells
     var cel      : Cel;
  
     var currentPos        : Vector3;
     var topLeftCorner  : Vector3;
 
     function Start()
     {
        lowestCost = Mathf.Infinity;
        v = 6;
        cellSize = 4;
  
  
        cel.obj    = agentTransform;
        cel.enemy  = enemyTransform;
        cel.color  = Color.red;
        scale = 2;
        topLeftCorner =Vector3 (transform.position.x-transform.localScale.x/scale ,transform.position.y  ,transform.position.z-transform.localScale.z/scale);
 
        cells = new Cel[v,v];///the size of the 2d array
        cellSizeX = transform.localScale.x / cellSize;//width
        cellSizeZ = transform.localScale.z / cellSize;//height
        for(i = 0 ; i < v ; i ++)
        {
          for(x = 0 ; x < v ; x ++)
          {
  
           ////THE CURRENT POSITION AND TYPE OF CELLS////
           //print(x);
           currentPos = topLeftCorner + Vector3(i*cellSizeX,0,x*cellSizeZ); ////current position of the cell in i,x coordonates
           cells[i,x] = cel;////each of cells of coordonates [1,1] or cells[1,2] etc will equal one cell
           cells[i,x].celPos =currentPos;
           ////THE CURRENT POSITION AND TYPE OF CELLS//// 
           parentCell = cells[i,x].currentCellParent;//parrentCell = the first cell in the list
         }
       }
     }
  
     function Update()
     {  
        for(i = 0 ; i < v ; i ++)
        {
          for(x = 0 ; x < v ; x ++)
          {
               //Now do all your checks and stuff.
          }
        }  
     }
 }
 
 class Cel extends System.ValueType {
 
     //Stuff
 }
  
        
  
  
  
  
        
  
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Nk.Andrei · Jul 26, 2013 at 09:51 PM 0
Share

Thanks for the reply...now I understand how much I still have to go through.....the thing that eludes me....what is the difference betwen a simple class Cel and class Cel extends System.ValueType....I mean what role does the SystemValueType has AND what effect does it have on classes...I also want to know the differences betwen classes with and without valueType. I tested the script with and without the valueType and it gives me different results and I want to understand why.Some example code would be nice.

avatar image Eric5h5 · Jul 26, 2013 at 09:56 PM 0
Share

Extending ValueType makes it a struct rather than a class. It doesn't look suitable for being a struct to me though.

avatar image Peter G · Jul 26, 2013 at 10:03 PM 0
Share

Hmmm. I liked it as a struct. It's relatively small, and I don't think it will change frequently, and it gets cloned like he wants. Why don't you like it as a struct @Eric5h5?

avatar image Peter G · Jul 26, 2013 at 10:06 PM 0
Share

And to Nk.Andrei, structs and classes have lots of differences. I would recommend googling it to learn more. Here's a basic overview.

avatar image
0

Answer by perchik · Jul 26, 2013 at 07:59 PM

I think there's all kinds of things wrong in your script. To answer your question though,

I don't see anywhere that you actually initialize a Cel object. Even when you create the list, allocating the space for Cels is different than creating a new Cel (by calling it's constructor). Since a Cel is never constructed, by default it has no h value

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

19 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

IndexOutOfRangeExeption - Array index is out of range 2 Answers

Error CS0029 Help? (Screenshot of Exact Error) 1 Answer

array problem 1 Answer

Texture2d[]: Array index is out of rang (Javascript) 3 Answers

IndexOutOfRangeException: Array index is out of range 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges