How to remove an object from the list using Remove function ?

I am using Raycast to delete an GameObject from the scene but it is not getting removed from the list.

RaycastHit hit3d;
if (hit3d.collider.tag=="Linetag")
  {
    tempGO = hit3d.transform.parent.gameObject;
    Destroy(tempGO);
    getAllLines.Remove(hit3d.transform.parent.gameObject);
    Debug.Log("Length of getAllLines = " + getAllLines.Count);
 }

After executing the code the GameObject gets destroyed but that GameObject is not getting removed from the list.The length of the list is intact after deletion(before and after have same values.)

RaycastHit hit3d;
if (hit3d.collider.tag=="Linetag")
  {
    tempGO = hit3d.transform.parent.gameObject;
  getAllLines.Remove(hit3d.transform.parent.gameObject);
 
    Destroy(tempGO);
    Debug.Log("Length of getAllLines = " + getAllLines.Count);
}

Before destroying the object remove it from the list.

1 Like

Removing from the list before destroying the object is a good idea, because Unity pretends that destroyed objects are equal to null, which could cause weird behavior in any function that implicitly tests whether things are equal (such as List.Remove).

However, I suspect that’s probably not the issue here, because Destroy() normally won’t actually destroy the object until the end of the current frame, and even a destroyed object should still compare as equal to itself (it just might also compare as equal to some other stuff).

Though I guess maybe there could be a problem due to the fact that you wrote out “hit3d.transform.parent.gameObject” instead of using the cached value “tempGO”, if the Destroy call somehow severed the link between parent and child? (Again, I still wouldn’t expect that to happen until the end of the frame.)

Is getAllLines a List, and are you 100% sure that List actually contains tempGO?

1 Like

Check the return value from Remove. It will return false if it wasn’t able to find the object in the list. You should also check if hit3d.transform.parent.gameObject is null, which will be the case if hit3d is not a child object.

I feel reasonably confident that if hit3d is not a child object, then hit3d.transform.parent would be null, and therefore hit3d.transform.parent.gameObject would throw a NullReferenceException.

1 Like

Hey now I changed the code…It is a bit more confusing for me.I am saving two different positions in two different lists.
I am saving the starting point position for Line Renderer in LinePositions0 and ending point position in LinePositions1.
Now when I delete the Line Renderer,I want to remove the positions related to that specific Line Renderer.How to achieve this?

List<Vector3> LinePositions0;
List<Vector3> LinePositions1;

//Adding the starting and ending points of a Line Renderer.
LinePositions0.Add(temp0);
LinePositions1.Add(temp1);

if (hit3d.collider.tag=="Linetag")
{
                 
 tempGO = hit3d.transform.parent.gameObject;
 Debug.Log("Length of lines = " + LinePositions0.Count);
 //Here I am looking to delete the starting and ending point of the raycast hit Line Renderer.
 LinePositions0.Remove(hit3d.transform.position);
 LinePositions1.Remove(hit3d.transform.position);

 Debug.Log("Length of lines after = " + LinePositions0.Count);
 //Destroys the Line renderer.
 Destroy(tempGO);

 }

I’d probably do something like this or implement a listener of some sort:

public class Line {
    Vector3 startPos, endPos;
   
    Line(Vector3 startPos, Vector3 endPos) {
        this.startPos = startPos;
        this.endPos = endPos;
    }
}

Dictionary<int, Line> lines = new Dictionary<int, Line>();

void AddLine(GameObject go, Vector3 start, Vector3 end) {
    lines.Add(go.GetInstanceID(), new Line(start, end));
}

void RemoveLine(GameObject go) {
    lines.Remove(go.GetInstance());
    Destroy(go);
}
1 Like

You were right actually I should try to remove the Lines intial and end points not the GameObject.Because I am saving the points not lines.So while deleting the gameobject I need to remove those coressponding start and end points from LinePositions0 . and LinePositions1 lists respectively.

Well, you need some way of figuring out which positions correspond to the object, or you can’t even get started. If you have some way of identifying the index of those positions within your list, you can use RemoveAt() instead of Remove().

But it sounds like Boz0r’s approach would probably serve you better: combine your start and end positions into a single data structure, and store them in a Dictionary instead of List(s). (But note the typo on line 17.)

Well, I never!

Did something similar

  public struct GetLineRenderPoints
    {
        public int goId;
        public GameObject collGo;
        public Vector3 startPoint;
        public Vector3 endPoint;

        public GetLineRenderPoints(int Id,GameObject Collidergo,Vector3 start,Vector3 end)
        {
            this.goId = Id;
            this.collGo = Collidergo;
            this.startPoint = start;
            this.endPoint = end;

        }

    }




if (hit3d.collider.tag=="Linetag")
 {
             
   tempGO = hit3d.transform.parent.gameObject;
   //Removing the hit object from the List using RemoveAll.
   holdList.RemoveAll(i => i.goId == tempGO.transform.GetChild(2).GetInstanceID());

   Destroy(tempGO);
   //Clearing already stored position including the above deleted Line positions.
   LinePositions0.Clear();
   LinePositions1.Clear();

    for (int i = 0; i < holdList.Count; i++)
     {

        LinePositions0.Add(holdList[i].startPoint);
        LinePositions1.Add(holdList[i].endPoint);

     }

  }

go.GetInstanceID() really helped… :slight_smile: