How can I add/remove/destroy more or less objects at runtime ?

The script is a bit long I’m not sure what I can reduce I will try.

When I’m running the program it’s starting by making the square formation.

What I’m trying to archive is that at each time in runtime if I change the numberOfSquadMembers value up or down add/remove to each squad the more/less value of squad members.

Same for the numberOfSquads value.

The problem is I’m not sure how to do it in the Update() how to add more squads/squad memebers or destroy when the values are less then the current ?

instantiate and destroy is the way the problem is how to maintenance keeping the current formation/s when adding or removing the squads/squads members.

The first script that generate first time the squads and the squads members :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SquadsGenerator : MonoBehaviour
{
	public GameObject squadPrefab;
	public GameObject squadMemberPrefab;
	public int numberOfSquads;
	public int numberOfMembersInsquad;

	private GameObject squadsParent;

	private void Start()
	{
		squadsParent = GameObject.Find("Squads");
		GenerateSquads(numberOfSquads, 
			numberOfMembersInsquad, squadMemberPrefab, squadPrefab);
	}

	// Update is called once per frame
	void Update()
	{
		
	}

	public void GenerateSquads(int squadsCount,
		int numberOfMembers,
		GameObject squadMemberPrefab, GameObject squadPrefab)
	{
		for (int i = 0; i < squadsCount; i++)
		{
			var newSquad = Instantiate(squadPrefab);
			newSquad.name = "Squad " + i;
			newSquad.tag = "Squad";
			newSquad.transform.parent = squadsParent.transform;

			for (int x = 0; x < numberOfMembers; x++)
			{
				var go = Instantiate(squadMemberPrefab);
				go.name = "Member " + x;
				go.tag = "Squad Member";
				go.transform.parent = newSquad.transform;

				switch (i % 6)
				{
					case 0: ColorSquad(go, Color.green); break;
					case 1: ColorSquad(go, Color.red); break;
					case 2: ColorSquad(go, Color.blue); break;
					case 3: ColorSquad(go, Color.yellow); break;
					case 4: ColorSquad(go, Color.cyan); break;
					case 5: ColorSquad(go, Color.magenta); break;
				}
			}
		}
	}

	private void ColorSquad(GameObject squad, Color color)
	{
		Renderer rend = squad.GetComponent<Renderer>();
		rend.material.SetColor("_Color", color);
	}
}

and this script handle the formations with the generated squads and member squads :

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class Formations : MonoBehaviour
{
    enum Formation
    {
        Square, Circle, Triangle
    }

    [Header("Main Settings")]
    [Space(5)]
    [Range(4, 100)]
    public int numberOfSquadMembers = 20;
    [Range(1, 20)]
    public int numberOfSquads = 1;
    [Range(0, 4)]
    public int columns = 4;
    public int gaps = 10;
    public int circleRadius = 10;
    public float yOffset = 0;
    [Range(3, 50)]
    public float moveSpeed = 3;
    [Range(3, 50)]
    public float rotateSpeed = 1;
    public float threshold = 0.1f;
    public bool randomSpeed = false;
    [Range(1, 100)]
    public int randSpeedMin = 1;
    [Range(1, 100)]
    public int randSpeedMax = 1;
    public bool startRandomFormation = false;
    public string currentFormation;

    private Formation formation;
    private List<Quaternion> quaternions = new List<Quaternion>();
    private List<Vector3> newpositions = new List<Vector3>();
    private bool move = false;
    private bool squareFormation = false;
    private List<GameObject> squadMembers = new List<GameObject>();
    private float[] step;
    private int[] randomSpeeds;
    private int index = 0;
    private bool ready = false;
    private GameObject[] squads;
    private Vector3 startVector;
    private Vector3 total;
    private List<Vector3> endpositions = new List<Vector3>();

    public void InitFormations()
    {
        if (startRandomFormation)
        {
            formation = (Formation)UnityEngine.Random.Range(0, Enum.GetNames(typeof(Formation)).Length);
        }
        else
        {
            formation = Formation.Square;
        }

        squads = GameObject.FindGameObjectsWithTag("Squad");
        for (int i = 0; i < squads.Length; i++)
        {
            foreach (Transform squadMember in squads*.transform)*

{
squadMembers.Add(squadMember.gameObject);
}
}

foreach (GameObject unit in squadMembers)
{
if (unit != null)
{
total += unit.transform.position;
}
}

Vector3 center = total / squadMembers.Count;
//Vector3 endPos = GameObject.Find(“Cube”).transform.position;
foreach (GameObject unit in squadMembers)
{
startVector = unit.transform.position - center;
endpositions.Add(/*endPos + */startVector);
}

currentFormation = formation.ToString();
ChangeFormation();

randomSpeeds = RandomSpeeds(randSpeedMin, randSpeedMax, squadMembers.Count);
step = new float[squadMembers.Count];

ready = true;
}

private void Start()
{
InitFormations();
}

// Update is called once per frame
void Update()
{
if (ready == true)
{
if (Input.GetKeyDown(KeyCode.C))
{
randomSpeeds = RandomSpeeds(randSpeedMin, randSpeedMax, squadMembers.Count);
foreach (int speedV in randomSpeeds)
{
if (index == randomSpeeds.Length)
index = 0;

step[index] = speedV * Time.deltaTime;
index++;
}

ChangeFormation();
}

if (move == true)
{
MoveToNextFormation();
}
}
}

private void ChangeFormation()
{
switch (formation)
{
case Formation.Square:
FormationSquare();
break;

case Formation.Circle:
FormationCircle();
break;

case Formation.Triangle:
FormationTriangle();
break;
}
}

private void FormationTriangle()
{
newpositions = new List();

int height = Mathf.CeilToInt((Mathf.Sqrt(8 * squadMembers.Count + 1f) - 1f) / 2);
int slots = (int)(height * (height + 1f) / 2f);

float verticalModifier = 1.25f; // * 1.25f to increase horizontal space
float horizontalModifier = 0.8f; // * 0.8f to decrease “vertical” space

float width = 0.5f * (height - 1f);
Vector3 startPos = new Vector3(width * horizontalModifier, 0f, (float)(height - 1f) * verticalModifier);

int finalRowCount = height - slots + squadMembers.Count;
for (int rowNum = 0; rowNum < height && newpositions.Count < squadMembers.Count; rowNum++)
{
for (int i = 0; i < rowNum + 1 && newpositions.Count < squadMembers.Count; i++)
{
float xOffset = 0f;

if (rowNum + 1 == height)
{
// If we’re in the last row, stretch it …
if (finalRowCount != 1)
{
// Unless there’s only one item in the last row.
// If that’s the case, leave it centered.

xOffset = Mathf.Lerp(
rowNum / 2f,
-rowNum / 2f,
i / (finalRowCount - 1f)
) * horizontalModifier;
}
}
else
{
xOffset = (i - rowNum / 2f) * horizontalModifier;
}

float yOffset = (float)rowNum * verticalModifier;

Vector3 position = new Vector3(
startPos.x + xOffset, 0f, startPos.y - yOffset);
newpositions.Add(position);

}
}

move = true;
formation = Formation.Square;
}

private Vector3 FormationSquarePositionCalculation(int index) // call this func for all your objects
{
float posX = (index % columns) * gaps;
float posY = (index / columns) * gaps;
return new Vector3(posX, posY);
}

private void FormationSquare()
{
newpositions = new List();
quaternions = new List();

for (int i = 0; i < squadMembers.Count; i++)
{
Vector3 pos = FormationSquarePositionCalculation(i);

//squadMembers*.transform.position = new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y);*
squadMembers*.transform.Rotate(new Vector3(0, -90, 0));*

//newpositions.Add(new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y));
newpositions.Add(new Vector3(endpositions_.x + pos.x, 0, endpositions*.y + pos.y));
}
move = true;
squareFormation = true;
formation = Formation.Circle;
}*_

private Vector3 FormationCirclePositionCalculation(Vector3 center, float radius, int index, float angleIncrement)
{
float ang = index * angleIncrement;
Vector3 pos;
pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
pos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
pos.y = center.y;
return pos;
}

private void FormationCircle()
{
newpositions = new List();
quaternions = new List();

Vector3 center = transform.position;
float radius = (float)circleRadius / 2;
float angleIncrement = 360 / squadMembers.Count;//(float)numberOfSquadMembers;
for (int i = 0; i < squadMembers.Count; i++)//numberOfSquadMembers; i++)
{
Vector3 pos = FormationCirclePositionCalculation(center, radius, i, angleIncrement);

var rot = Quaternion.LookRotation(center - pos);

if (Terrain.activeTerrain == true)
pos.y = Terrain.activeTerrain.SampleHeight(pos);
pos.y = pos.y + yOffset;
newpositions.Add(pos);
quaternions.Add(rot);
}
move = true;
squareFormation = false;
formation = Formation.Triangle;
}

private void MoveToNextFormation()
{
if (randomSpeed == false)
{
if (step.Length > 0)
step[0] = moveSpeed * Time.deltaTime;
}

for (int i = 0; i < squadMembers.Count; i++)
{
squadMembers_.transform.LookAt(newpositions*);*_

if (randomSpeed == true)
{
squadMembers*.transform.position =*
Vector3.MoveTowards(squadMembers.transform.position, newpositions_, step*);
}
else
{_

_squadMembers.transform.position =
Vector3.MoveTowards(squadMembers.transform.position, newpositions, step[0]);
}*_

if (Vector3.Distance(squadMembers_.transform.position, newpositions*) < threshold)
{
if (squareFormation == true)
{
Vector3 degrees = new Vector3(0, 0, 0);
Quaternion quaternion = Quaternion.Euler(degrees);
squadMembers.transform.rotation = Quaternion.Slerp(squadMembers.transform.rotation, quaternion, rotateSpeed * Time.deltaTime);
}
else
{
squadMembers.transform.rotation = Quaternion.Slerp(squadMembers.transform.rotation, quaternions, rotateSpeed * Time.deltaTime);
}
}
}
}*_

private static int[] RandomSpeeds(int min, int max, int howMany)
{
int[] myNumbers = new int[howMany];

for (int i = 0; i < howMany; i++)
{
myNumbers = UnityEngine.Random.Range(min, max);
}

return myNumbers;
}
}

Use Object.Destroy(GameObject or Component of GameObject);