Search Unity

Help: Updating an Element in a NativeList

Discussion in 'Entity Component System' started by Bodyclock, Nov 17, 2020.

  1. Bodyclock

    Bodyclock

    Joined:
    May 8, 2018
    Posts:
    172
    Hi All,
    I'm trying to do something very simple - update an existing element in a NativeList. I understand that a struct is a value type. I can get a copy of the struct and update a property, but I can't assign it back at the same index (required as these are mesh vertices).
    I get "Cannot modify the return value of 'AreaJob.VertexList' because it is not a variable".

    Code (CSharp):
    1.         private int SetVertexIndex(float3 point, int external)
    2.         {
    3.             int index;
    4.             if (vertexCheck.ContainsKey(point))
    5.             {
    6.                 index = vertexCheck[point];
    7.  
    8.                 //Copy of the Vertex struct.
    9.                 Vertex vertex = VertexList[index];
    10.                 //Update a property. This works.
    11.                 vertex.Usage += 1;
    12.                 //Assign the vertex copy back to the list. This doesn't work.
    13.                 VertexList[index] = vertex;
    14.  
    15.                 //Not much documentation on this extension but apparently returns a ref??
    16.                 //Still didn't work.
    17.                 //VertexList.ElementAt(index).Usage += 1;
    18.             }
    19.             else
    20.             {
    21.                 index = VertexList.Length;
    22.                 vertexCheck.TryAdd(point, index);
    23.                 VertexList.Add(new Vertex(point, external));        
    24.             }
    25.             return index;
    26.         }
    This is so simple I think I must be very stupid. Apologies for that. Any help appreciated. :)
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    It should work. Something else is wrong. Hard to say what though without more code and a more complete error message.

    Also, yes, ElementAt returns a ref. It works as you would expect it to.
     
  3. Bodyclock

    Bodyclock

    Joined:
    May 8, 2018
    Posts:
    172
    Thanks. But I'm not sure where else there could be an issue. Without that code to update the existing element, it runs perfectly and produces beautiful procedural meshes. :)

    Mesh.png

    The error message is a Console/IDE error message and there is nothing more verbose.
    The only thing I could think of was that the NativeList is external to the job but I tried to change it so it's instantiated in the Job but it still doesn't compile. Plus everything else works and I can Add to the list quite happily.
    So VertexList.ElementAt(index).Usage += 1; would be the correct way to use it in this case?
     
  4. Arberk

    Arberk

    Joined:
    Feb 3, 2014
    Posts:
    5
    VertexList is property, copy it's value to local variable

    Code (CSharp):
    1. var v = VertexList;
    2. v[index] = vertex;
     
  5. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    Yes. That's what I was suspecting too. That solution works. ElementAt will also work.
     
  6. Bodyclock

    Bodyclock

    Joined:
    May 8, 2018
    Posts:
    172
    This didn't work either.

    Code (CSharp):
    1.  
    2.                 //Copy of the Vertex struct.
    3.                 var v = VertexList;
    4.                 Vertex vertex = v[index];
    5.                 ////Update a property. This works.
    6.                 vertex.Usage = 10;
    7.                 //Assign the vertex copy back to the list. This doesn't work.
    8.                 v[index] = vertex;
    9.  
    10.                 //Not much documentation on this extension but apparently returns a ref??
    11.                 //Still didn't work.
    12.                 //v.ElementAt(index).Usage += 1;
     
  7. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    406
    Vertex vertex = VertexList[index];
    vertex.Value = Able;
    VertexList[index] = vertex;
     
  8. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    Can we see the definition of VertexList? Something really funky seems to be happening.

    As for ElementAt:
    Code (CSharp):
    1. ref var vertex = ref VertexList.ElementAt(index);
    2. vertex.Usage += 1;
     
  9. Bodyclock

    Bodyclock

    Joined:
    May 8, 2018
    Posts:
    172
    Ok, as Arbex said, it was the fact that VertexList was an AutoProperty that was messing it up (as well as me). Thanks all for the suggestions.
    And in fact after changing it.
    Code (CSharp):
    1. vertexList.ElementAt(index).Usage += 1;
    worked just fine.