Moving multiple objects in a loop

I have a tray of objects at the bottom of the screen starting from 150px on X screenspace that are ordered in a list from left to right, what I’m trying to do is when one of the objects is removed from the tray and the list, move all objects to the right/lower on the list 250px to the left to fill in the space left by the removed object. With my code right now, all the objects are moving to the left with the first object being at the start of the tray(150px), when they should only move over to the left 250px from their current position. I get the position of the removed piece in one function with

selectedPos = Camera.main.ScreenToWorldPoint(selectedPiece.transform.position);

then try to move all the pieces over 250px to the left with

void RemoveFromTray(GameObject p)
    {
        for (int i = 0; i < pieceTray.Count; i++)
        {
            if (pieceTray[i].gameObject == selectedPiece)
            {
                removedPieceIndex = i;
            }
        }
       pieceTray.Remove(p);
       float spacing = 150;
       for (int i = removedPieceIndex; i < pieceTray.Count; i++)
       {
           GameObject piece = pieceTray[i];
           Vector3 newPos = Camera.main.ScreenToWorldPoint(new Vector3(selectedPos.x + spacing, 0 + 175, 10));
           Debug.Log(newPos);
           piece.transform.DOMove(new Vector3(newPos.x, piece.transform.position.y, piece.transform.position.z), 0.5f);
           spacing += 250;
       }
    }

Not sure why it’s not taking the selectedPos.x into account and using that as the start point, it instead is just using the 150px as the start point for all moved objects. Any help would be appreciated, thanks.

I would recommend using a Horizontal Layout Group: Horizontal Layout Group | Unity UI | 1.0.0

The layout group will take care of this repositioning for you automatically when one of the elements is destroyed or deactivated.

These objects aren’t UI elements, they are meshes in scene, don’t layout groups only work with UI?

Ah sorry I was confused because you were mentioning screen space coordinates. But if you make a Canvas that uses Screen Space - Camera, you can actually child 3D GameObjects to UI elements in that canvas and use the UI elements to position the world space objects. So that’s one option.

Anyway in regards to your code, it doesn’t look like you’re taking the current position of the current piece in your for loop into account at all when calculating the new X position.

Thanks for the replies, I think I was just making it harder than it had to be, I got it working by just moving each object to the position of the next object in the list.

void RemoveFromTray(GameObject p)
    {
        for (int i = 0; i < pieceTray.Count; i++)
        {
            if (pieceTray[i].gameObject == selectedPiece)
            {
                removedPieceIndex = i;
            }
        }     
        for (int i = removedPieceIndex + 1; i < pieceTray.Count; i++)
        {
            GameObject piece = pieceTray[i];
            Vector3 newPos = pieceTray[i-1].gameObject.transform.position;
            piece.transform.DOMove(new Vector3(newPos.x, piece.transform.position.y, piece.transform.position.z), 0.5f);
        }
        pieceTray.Remove(p);
    }
1 Like