0
\$\begingroup\$
private void FindDistances()
    {
        List<float> distances = new List<float>();
        List<Vector3> positions = new List<Vector3>();

        for (int i = 0; i < objects.Count; i++)
        {
            distances.Add(Vector3.Distance(EndStartPoints[0].transform.position, objects[i].transform.position));
            positions.Add(objects[i].transform.position);
        }
        distances.Sort();
    }

For example in distances the first 3 indexes are:

0 = 10
1 = 10
2 = 10

But in the positions List every object have another position. So distance 10 in index 0 is not in the same position as distance 10 in index 2. S o i want somehow to merge the Lists so i know that index 0 distance 10 is at position...x,y,z and index 2 distance 10 is at position...x,y,z

Like keys and values ? Not sure.

Then i want to get from the first 3 distance random of one distance and his position. For example if i in the List distances i have cases of same distance pick random distance and it's position.

If it's only one distance then just get his position.

Last thing i will want then to destroy or color the object at the position of the distance. So i have a List called objects.

So if i picked for example distance index 1 then destroy or color the object on the distance position.

What i tried so far:

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

public class TestGenerator : MonoBehaviour
{
    [System.Serializable]
    public class PosDisPair //Name the pair however you like
    {
        public float Distance;
        public Vector3 Pos;
    }

    public GameObject Node;
    public Vector3 nodeScale = new Vector3(4, 1, 4);
    [Range(3, 100)]
    public int mapSize = 10;
    public float Spacing = 10;
    public float spawnSpeed = 5;
    private List<GameObject> objects = new List<GameObject>();
    private List<GameObject> EndStartPoints = new List<GameObject>();
    private int currentMapSize;
    private List<PosDisPair> pairList = new List<PosDisPair>();

    private void Start()
    {
        currentMapSize = mapSize;
        Generate();
        GenerateRandom(mapSize);
    }

    private void Generate()
    {
        if (objects.Count > 0)
            objects = new List<GameObject>();

        if (Node == null)
            Node = UnityEngine.GameObject.FindGameObjectWithTag("Main Node");

        for (int x = 0; x < mapSize; x++)
        {
            float positionWidth = Spacing * (float)x;

            for (int z = 0; z < mapSize; z++)
            {
                float positionHieght = Spacing * (float)z;
                GameObject block = Instantiate(Node, Vector3.zero, Node.transform.rotation) as GameObject;
                block.transform.parent = transform;
                block.transform.localPosition = new Vector3(positionWidth, 0, positionHieght);
                block.transform.localScale = new Vector3(nodeScale.x, nodeScale.y, nodeScale.z);
                block.tag = "NodeDestroyable";
                objects.Add(block);
            }
        }
    }

    public void GenerateNew()
    {
        currentMapSize = mapSize;

        DestroyNodes();

        Node = UnityEngine.GameObject.FindGameObjectWithTag("Main Node");
        Generate();
        GenerateRandom(mapSize);

        FindDistances();
    }

    public void DestroyNodes()
    {
        GameObject[] nodes = UnityEngine.GameObject.FindGameObjectsWithTag("NodeDestroyable");

        if (nodes.Length == 0)
        {
            //Debug.Log("No nodes to destroy found");
        }
        else
        {
            for (int i = 0; i < nodes.Length; i++)
            {
                DestroyImmediate(nodes[i]);
            }
        }
    }

    private void Update()
    {
        Erase();
    }

    private void Erase()
    {
        if (Input.GetMouseButton(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                if (hit.collider.tag == "NodeDestroyable")
                {
                    Destroy(hit.collider.gameObject);
                }
            }
        }
    }

    private void GenerateRandom(int gridSize)
    {
        List<int> selectedIndexes = new List<int>();

        //Create an array for indexes of the TOP side
        var arr = new int[gridSize];
        for (int i = 0; i < gridSize; i++)
        {
            arr[i] = i;
        }
        int mynum = arr[Random.Range(0, arr.Length)];
        GameObject Top = objects[mynum];
        selectedIndexes.Add(mynum);

        //Create an array for indexes of the LEFT side
        int mynum1 = 0;
        var arr1 = new int[gridSize];
        for (int i = 0; i < gridSize; i++)
        {
            arr1[i] = i * gridSize;
        }
        do
        {
            mynum1 = arr1[Random.Range(0, arr1.Length)];
        }
        while (selectedIndexes.Contains(mynum1));
        GameObject Left = objects[mynum1];
        selectedIndexes.Add(mynum1);


        //Create an array for indexes of the BOTTOM side
        int mynum2 = 0;
        var arr2 = new int[gridSize];
        for (int i = 0; i < gridSize; i++)
        {
            arr2[i] = (gridSize * (gridSize - 1)) + i;   //Reach the last row and iterate with i.
        }
        do
        {
            mynum2 = arr2[Random.Range(0, arr2.Length)];
        }
        while (selectedIndexes.Contains(mynum2));
        GameObject Bottom = objects[mynum2];
        selectedIndexes.Add(mynum2);

        //Create an array for indexes of the RIGHT side
        int mynum3 = 0;
        var arr3 = new int[gridSize];
        for (int i = 0; i < gridSize; i++)
        {
            arr3[i] = (i * gridSize) + gridSize - 1;
        }
        do
        {
            mynum3 = arr3[Random.Range(0, arr3.Length)];
        }
        while (selectedIndexes.Contains(mynum3));
        GameObject Right = objects[mynum3];
        selectedIndexes.Add(mynum3);

        /*DestroyImmediate(Right);
        DestroyImmediate(Left);
        DestroyImmediate(Top);
        DestroyImmediate(Bottom);*/

        EndStartPoints = new List<GameObject>();
        EndStartPoints.Add(Left);
        EndStartPoints.Add(Right);

        selectedIndexes.Clear();
    }

    private void OnValidate()
    {
        if (currentMapSize != mapSize)
        {
            UnityEditor.EditorApplication.delayCall += () =>
            {
                GenerateNew();
            };
        }
    }

    private void FindDistances()
    {
        for (int i = 0; i < objects.Count;)
        {
            PosDisPair pairToAdd = new PosDisPair();
            pairToAdd.Distance = Vector3.Distance(EndStartPoints[0].transform.position, objects[i].transform.position);
            pairToAdd.Pos = objects[i].transform.position;
            pairList.Add(pairToAdd);
        }

        pairList.Sort(delegate (PosDisPair a, PosDisPair b) {
            return (a.Distance.CompareTo(b.Distance));
        });
    }

    private void MoveInPath(List<float> distances, List<Vector3> positions)
    {
        for (int i = 0; i < pairList.Count; i++)
        {

        }
    }
}

In the method GenerateNew i'm calling the method: FindDistances(); And inside FindDistances i'm doing:

private void FindDistances()
        {
            for (int i = 0; i < objects.Count;)
            {
                PosDisPair pairToAdd = new PosDisPair();
                pairToAdd.Distance = Vector3.Distance(EndStartPoints[0].transform.position, objects[i].transform.position);
                pairToAdd.Pos = objects[i].transform.position;
                pairList.Add(pairToAdd);
            }

            pairList.Sort(delegate (PosDisPair a, PosDisPair b) {
                return (a.Distance.CompareTo(b.Distance));
            });
        }

And it keep adding to pairList all the time. Then it's raising the memory usage to 2.3GB and stuck/freezing everything i need to shut down the pc.

And the List objects contain only 100 items but i see in pairList over 2 million items i could debug it for a second.

Not sure why it keep adding items to pairList.

The script is working on editor mode so once i'm opening the project it's executing the script and stuck everything.

I also have another script i'm using for buttons:

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

[CustomEditor(typeof(TestGenerator))]
public class GenerateButton : Editor
{
    public override void OnInspectorGUI()
    {
        TestGenerator Generate = (TestGenerator)target;

        if (GUILayout.Button("Generate New"))
        {
            Generate.GenerateNew();
        }

        DrawDefaultInspector();

        if (GUILayout.Button("Destroy Nodes"))
        {
            Generate.DestroyNodes();
        }
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ You may want to also empty your lists when you generate new objects. Right now, if you call GenerateNew() the existing list of distances and points is retained and all the new GOs are compared and have their data added to that list, leading to an eventual memory leak. \$\endgroup\$ Aug 17, 2017 at 18:24

1 Answer 1

0
\$\begingroup\$

I could not understand the operations you want to perform but I can also modify the answer for those needs if you clarify it more (The part after your "Like keys and values ? Not sure." sentence). For the solution I suggest you to create a little class for holding the position and the distance as pairs (Can also be struct I guess):

[Serializable]
public class PosDisPair           //Name the pair however you like
{
      public float Distance;
      public Vector3 Pos;
 }

Create a list from that pairs as follows:

List<PosDisPair> pairList = new List<PosDisPair>();

Modify your for loop to set the elements of the list:

for (int i = 0; i < objects.Count; i++){
     PosDisPair pairToAdd = new PosDisPair();
     pairToAdd.Distance = Vector3.Distance(EndStartPoints[0].transform.position, objects[i].transform.position); 
     pairToAdd.Pos = objects[i].transform.position;
     pairList.Add(pairToAdd);              
}

And finally sort the list with a custom mehtod:

pairList.Sort(delegate(PosDisPair a, PosDisPair b) {
     return (a.Distance.CompareTo(b.Distance));
});

Now you can easily access and modify the items you desire, and manipulate the list according to your needs.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .