Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How can I update the array of objects depending on the spawned objects ?

Discussion in 'Scripting' started by haimmoshe, Feb 20, 2018.

  1. haimmoshe

    haimmoshe

    Joined:
    Jun 3, 2017
    Posts:
    237
    The first script is spawning new objects:

    Code (csharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. using Random = UnityEngine.Random;
    5.  
    6. [ExecuteInEditMode]
    7. public class SpawnObjects : MonoBehaviour
    8. {
    9.     // for tracking properties change
    10.     private Vector3 _extents;
    11.     private int _objectCount;
    12.     private float _objectSize;
    13.  
    14.     public GameObject objectToSpawn;
    15.  
    16.     /// <summary>
    17.     ///     How far to place spheres randomly.
    18.     /// </summary>
    19.     public Vector3 Extents;
    20.  
    21.     /// <summary>
    22.     ///     How many spheres wanted.
    23.     /// </summary>
    24.     public int ObjectCount;
    25.  
    26.     public float ObjectSize;
    27.  
    28.     private void OnValidate()
    29.     {
    30.         // prevent wrong values to be entered
    31.         Extents = new Vector3(Mathf.Max(0.0f, Extents.x), Mathf.Max(0.0f, Extents.y), Mathf.Max(0.0f, Extents.z));
    32.         ObjectCount = Mathf.Max(0, ObjectCount);
    33.         ObjectSize = Mathf.Max(0.0f, ObjectSize);
    34.     }
    35.  
    36.     private void Reset()
    37.     {
    38.         Extents = new Vector3(250.0f, 20.0f, 250.0f);
    39.         ObjectCount = 100;
    40.         ObjectSize = 20.0f;
    41.     }
    42.  
    43.     private void Update()
    44.     {
    45.         UpdateSpheres();
    46.     }
    47.  
    48.     private void UpdateSpheres()
    49.     {
    50.         if (Extents == _extents && ObjectCount == _objectCount && Mathf.Approximately(ObjectSize, _objectSize))
    51.             return;
    52.  
    53.         // cleanup
    54.         var spheres = GameObject.FindGameObjectsWithTag("SpawnObject");
    55.         foreach (var t in spheres)
    56.         {
    57.             if (Application.isEditor)
    58.             {
    59.                 DestroyImmediate(t);
    60.             }
    61.             else
    62.             {
    63.                 Destroy(t);
    64.             }
    65.         }
    66.  
    67.         var withTag = GameObject.FindWithTag("Terrain");
    68.         if (withTag == null)
    69.             throw new InvalidOperationException("Terrain not found");
    70.  
    71.         for (var i = 0; i < ObjectCount; i++)
    72.         {
    73.             var o = Instantiate(objectToSpawn);
    74.             o.tag = "SpawnObject";
    75.             o.transform.localScale = new Vector3(ObjectSize, ObjectSize, ObjectSize);
    76.             o.transform.parent = transform;
    77.  
    78.             // get random position
    79.             var x = Random.Range(-Extents.x, Extents.x);
    80.             var y = Random.Range(10, Extents.y); //Extents.y; // sphere altitude relative to terrain below
    81.             var z = Random.Range(-Extents.z, Extents.z);
    82.  
    83.             // now send a ray down terrain to adjust Y according terrain below
    84.             var height = 10000.0f; // should be higher than highest terrain altitude
    85.             var origin = new Vector3(x, height, z);
    86.             var ray = new Ray(origin, Vector3.down);
    87.             RaycastHit hit;
    88.             var maxDistance = 20000.0f;
    89.             var nameToLayer = LayerMask.NameToLayer("Terrain");
    90.             var layerMask = 1 << nameToLayer;
    91.             if (Physics.Raycast(ray, out hit, maxDistance, layerMask))
    92.             {
    93.                 var distance = hit.distance;
    94.                 y = height - distance + y; // adjust
    95.             }
    96.             else
    97.             {
    98.                 Debug.LogWarning("Terrain not hit, using default height !");
    99.             }
    100.  
    101.             // place !
    102.             o.transform.position = new Vector3(x, y, z);
    103.         }
    104.  
    105.         _extents = Extents;
    106.         _objectCount = ObjectCount;
    107.         _objectSize = ObjectSize;
    108.     }
    109. }
    110.  
    The second script is trying to find the tagged "SpawObject" objects:

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Linq;
    5. using UnityEngine;
    6.  
    7. public class ShowMeshBounds : MonoBehaviour
    8. {
    9.     public GameObject[] objectsToDraw;
    10.     public GameObject prefabEffect;
    11.     public Color color = Color.green;
    12.  
    13.     private Vector3 v3FrontTopLeft;
    14.     private Vector3 v3FrontTopRight;
    15.     private Vector3 v3FrontBottomLeft;
    16.     private Vector3 v3FrontBottomRight;
    17.     private Vector3 v3BackTopLeft;
    18.     private Vector3 v3BackTopRight;
    19.     private Vector3 v3BackBottomLeft;
    20.     private Vector3 v3BackBottomRight;
    21.  
    22.     private float counter = 0;
    23.     public bool animateLines;
    24.     public float speed = 1f;
    25.  
    26.     private List<GameObject> allLines = new List<GameObject>();
    27.     private List<GameObject> instancesToMove = new List<GameObject>();
    28.     private Vector3 endPos;
    29.  
    30.     private void Start()
    31.     {
    32.         DrawObjects();
    33.     }
    34.  
    35.     private void DrawObjects()
    36.     {
    37.         objectsToDraw = GameObject.FindGameObjectsWithTag("SpawnObject");
    38.  
    39.         for (int i = 0; i < objectsToDraw.Length; i++)
    40.         {
    41.             CalcPositons(objectsToDraw[i]);
    42.             DrawBox();
    43.         }
    44.  
    45.         DuplicatePrefabEffects(allLines.Count);
    46.         StartCoroutine(moveStuff());
    47.     }
    48.  
    49.     private void DuplicatePrefabEffects(int duplicationNumber)
    50.     {
    51.             for (int i = 0; i < duplicationNumber; i++)
    52.             {
    53.                 var go = Instantiate(prefabEffect);
    54.                 go.tag = "Duplicated Prefab";
    55.                 go.name = "Duplicated Prefab";
    56.                 instancesToMove.Add(go);
    57.             }
    58.     }
    59.  
    60.     void CalcPositons(GameObject objectToDrawTransform)
    61.     {
    62.         Bounds bounds = objectToDrawTransform.GetComponent<MeshFilter>().sharedMesh.bounds;
    63.  
    64.         Vector3 v3Center = bounds.center;
    65.         Vector3 v3Extents = bounds.extents;
    66.  
    67.         v3FrontTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z);  // Front top left corner
    68.         v3FrontTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z);  // Front top right corner
    69.         v3FrontBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z);  // Front bottom left corner
    70.         v3FrontBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z);  // Front bottom right corner
    71.         v3BackTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z);  // Back top left corner
    72.         v3BackTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z);  // Back top right corner
    73.         v3BackBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z);  // Back bottom left corner
    74.         v3BackBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z);  // Back bottom right corner
    75.  
    76.         v3FrontTopLeft = objectToDrawTransform.transform.TransformPoint(v3FrontTopLeft);
    77.         v3FrontTopRight = objectToDrawTransform.transform.TransformPoint(v3FrontTopRight);
    78.         v3FrontBottomLeft = objectToDrawTransform.transform.TransformPoint(v3FrontBottomLeft);
    79.         v3FrontBottomRight = objectToDrawTransform.transform.TransformPoint(v3FrontBottomRight);
    80.         v3BackTopLeft = objectToDrawTransform.transform.TransformPoint(v3BackTopLeft);
    81.         v3BackTopRight = objectToDrawTransform.transform.TransformPoint(v3BackTopRight);
    82.         v3BackBottomLeft = objectToDrawTransform.transform.TransformPoint(v3BackBottomLeft);
    83.         v3BackBottomRight = objectToDrawTransform.transform.TransformPoint(v3BackBottomRight);
    84.     }
    85.  
    86.     void DrawBox()
    87.     {
    88.         SpawnLineGenerator(v3FrontTopLeft, v3FrontTopRight, color);
    89.         SpawnLineGenerator(v3FrontTopRight, v3FrontBottomRight, color);
    90.         SpawnLineGenerator(v3FrontBottomRight, v3FrontBottomLeft, color);
    91.         SpawnLineGenerator(v3FrontBottomLeft, v3FrontTopLeft, color);
    92.  
    93.         SpawnLineGenerator(v3BackTopLeft, v3BackTopRight, color);
    94.         SpawnLineGenerator(v3BackTopRight, v3BackBottomRight, color);
    95.         SpawnLineGenerator(v3BackBottomRight, v3BackBottomLeft, color);
    96.         SpawnLineGenerator(v3BackBottomLeft, v3BackTopLeft, color);
    97.  
    98.         SpawnLineGenerator(v3FrontTopLeft, v3BackTopLeft, color);
    99.         SpawnLineGenerator(v3FrontTopRight, v3BackTopRight, color);
    100.         SpawnLineGenerator(v3FrontBottomRight, v3BackBottomRight, color);
    101.         SpawnLineGenerator(v3FrontBottomLeft, v3BackBottomLeft, color);
    102.     }
    103.  
    104.     void SpawnLineGenerator(Vector3 start, Vector3 end, Color color)
    105.     {
    106.         GameObject myLine = new GameObject();
    107.  
    108.         myLine.transform.parent = transform;
    109.  
    110.         myLine.tag = "FrameLine";
    111.         myLine.name = "FrameLine";
    112.  
    113.         myLine.AddComponent<LineRenderer>();
    114.         myLine.AddComponent<EndHolder>();
    115.         myLine.GetComponent<EndHolder>().EndVector = end;
    116.         LineRenderer lr = myLine.GetComponent<LineRenderer>();
    117.         lr.material = new Material(Shader.Find("Particles/Alpha Blended Premultiply"));
    118.         lr.startColor = color;
    119.         lr.useWorldSpace = false;
    120.         lr.endColor = color;
    121.         lr.startWidth = 0.1f;//0.03f;
    122.         lr.endWidth = 0.1f;//0.03f;
    123.         lr.SetPosition(0, start);
    124.         lr.SetPosition(1, start);
    125.  
    126.         allLines.Add(myLine);
    127.     }
    128.  
    129.     IEnumerator moveStuff()
    130.     {
    131.         for (int i = 0; i < allLines.Count; i++)
    132.         {
    133.             counter = 0;
    134.  
    135.             while (Vector3.Distance(instancesToMove[i].transform.position, endPos) > 0.1f)
    136.             {
    137.                 counter++;
    138.                 endPos = allLines[i].GetComponent<EndHolder>().EndVector;
    139.                 Vector3 startPos = allLines[i].GetComponent<LineRenderer>().GetPosition(0);
    140.                
    141.                 instancesToMove[i].transform.position =
    142.                     Vector3.MoveTowards(startPos, endPos, counter / 25f * speed);
    143.  
    144.                 allLines[i].GetComponent<LineRenderer>().SetPosition(1, instancesToMove[i].transform.position);//tempPos);
    145.  
    146.                 yield return null;
    147.             }
    148.         }
    149.     }
    150. }
    151.  
    Inside DrawObjects:

    Code (csharp):
    1.  
    2. objectsToDraw = GameObject.FindGameObjectsWithTag("SpawnObject");
    3.  
    For example if I spawned 12 new objects then using break point I see when running the game that objectsToDraw contains 12 objects.

    Then everything is working I'm not getting any errors or exceptions.

    But in the editor in the inspector instead see 12 objects on Objects To Draw I see Missing (GameObject)
    I don't understand what the spawn script is destroying and not sure how to fix it.

    For example in this screenshot I spawned 5 objects , everything is working but I see in Objects to DRaw Missing (GameObject)

     
  2. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    it looks like you are deleting the gameobjects

    Code (CSharp):
    1. // cleanup
    2.         var spheres = GameObject.FindGameObjectsWithTag("SpawnObject");
    3.         foreach (var t in spheres)
    4.         {
    5.             if (Application.isEditor)
    6.             {
    7.                 DestroyImmediate(t);
    8.             }
    9.             else
    10.             {
    11.                 Destroy(t);
    12.             }
    13.         }
     
    haimmoshe likes this.
  3. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    Why are you changing the name and tag?

    go.tag = "Duplicated Prefab";
    go.name = "Duplicated Prefab";
     
  4. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    i'm note sure what this means. can you give more details? what values are you changing?
     
  5. haimmoshe

    haimmoshe

    Joined:
    Jun 3, 2017
    Posts:
    237
    What I don't understand is what objects the first script the SpawnObjects is destroying ? I mean it's creating for example 10 new spawned objects and then destroy them right away ? But I keep see the 10 objects in the Hierarchy. So what is it really destroying what objects ? And if I see in the Hierarchy the 10 objects and in the second script I'm finding them by tag and I see that the variable objectsToDraw is containing the 10 objects which is strange because if they were destroyed how can I find them ? And then why I see this Missing (Game Object) ? And yet everything is working as I wanted but I don't understanding the destroying logic and how to fix the Missing (Game Object) ?
     
  6. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    are you setting the size of objectsToDraw in the inspector?
    You must be, setting it to 5 or 12 or what ever. That creates an empty array, and you're right you are not finding any objects with the tag, so the array is still empty.
     
  7. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    One more issue I see. the first script SpawnObjects is creating the objects via the Update() function and the second script ShowMeshBounds is doing it's check in the Start() function.
    So the second script is checking for the spawned objects, but they haven't been created yet.

    Add these Debugs to the script so you can see what it's doing.

    First script
    Code (CSharp):
    1. private void UpdateSpheres()
    2.     {
    3.         Debug.Log("SpawnObjects Update Started");
    4.         if (Extents == _extents && ObjectCount == _objectCount && Mathf.Approximately(ObjectSize, _objectSize))
    5.             return;
    6.         // cleanup
    7.         var spheres = GameObject.FindGameObjectsWithTag("SpawnObject");
    8.         foreach (var t in spheres)
    9.         {
    10.             if (Application.isEditor)
    11.             {
    12.                 DestroyImmediate(t);
    13.             }
    14.             else
    15.             {
    16.                 Destroy(t);
    17.             }
    18.         }
    Second script
    Code (CSharp):
    1.     private void Start()
    2.     {
    3.         Debug.Log("ShowMeshBounds Started");
    4.         DrawObjects();
    5.         Debug.Log("ShowMeshBounds Completed");
    6.     }
    7.     private void DrawObjects()
    8.     {
    9.         objectsToDraw = GameObject.FindGameObjectsWithTag("SpawnObject");
    10.         Debug.Log("objectsToDraw.Length : " + objectsToDraw.Length);
    11.         for (int i = 0; i < objectsToDraw.Length; i++)
    12.         {
    13.             CalcPositons(objectsToDraw[i]);
    14.             DrawBox();
    15.         }
    16.         DuplicatePrefabEffects(allLines.Count);
    17.         StartCoroutine(moveStuff());
    18.     }
     
    haimmoshe likes this.