- Home /
How can I keep spawning new gameobjects and use them with another script ? They are getting destroyed
The first script is attached to a empty GameObject:
In the cleanup part if I will not make DestroyImmediate then it will keep spawning new gameobjects. So if for example in the Inspector I'm changing the variable ObjectCount to 5 and then if not making DestroyImmediate it will keep creating new objects even if the value in ObjectCount is still for example 5. On the other hand if I destroy the objects I can't use them anymore. So I'm a bit confused.
How can I spawn and create the new objects by changing the ObjectCount value in real time and to be able to use the created objects ?
using System;
using UnityEngine;
using Random = UnityEngine.Random;
[ExecuteInEditMode]
public class SpawnObjects : MonoBehaviour
{
// for tracking properties change
private Vector3 _extents;
private int _objectCount;
private float _objectSize;
public GameObject objectToSpawn;
/// <summary>
/// How far to place spheres randomly.
/// </summary>
public Vector3 Extents;
/// <summary>
/// How many spheres wanted.
/// </summary>
public int ObjectCount;
public float ObjectSize;
private void OnValidate()
{
// prevent wrong values to be entered
Extents = new Vector3(Mathf.Max(0.0f, Extents.x), Mathf.Max(0.0f, Extents.y), Mathf.Max(0.0f, Extents.z));
ObjectCount = Mathf.Max(0, ObjectCount);
ObjectSize = Mathf.Max(0.0f, ObjectSize);
}
private void Reset()
{
Extents = new Vector3(250.0f, 20.0f, 250.0f);
ObjectCount = 100;
ObjectSize = 20.0f;
}
private void Update()
{
UpdateSpheres();
}
private void UpdateSpheres()
{
if (Extents == _extents && ObjectCount == _objectCount && Mathf.Approximately(ObjectSize, _objectSize))
return;
// cleanup
var spheres = GameObject.FindGameObjectsWithTag("SpawnObject");
foreach (var t in spheres)
{
if (Application.isEditor)
{
DestroyImmediate(t);
}
else
{
Destroy(t);
}
}
var withTag = GameObject.FindWithTag("Terrain");
if (withTag == null)
throw new InvalidOperationException("Terrain not found");
for (var i = 0; i < ObjectCount; i++)
{
var o = Instantiate(objectToSpawn);
o.tag = "SpawnObject";
o.transform.localScale = new Vector3(ObjectSize, ObjectSize, ObjectSize);
o.transform.parent = transform;
// get random position
var x = Random.Range(-Extents.x, Extents.x);
var y = Random.Range(10, Extents.y); //Extents.y; // sphere altitude relative to terrain below
var z = Random.Range(-Extents.z, Extents.z);
// now send a ray down terrain to adjust Y according terrain below
var height = 10000.0f; // should be higher than highest terrain altitude
var origin = new Vector3(x, height, z);
var ray = new Ray(origin, Vector3.down);
RaycastHit hit;
var maxDistance = 20000.0f;
var nameToLayer = LayerMask.NameToLayer("Terrain");
var layerMask = 1 << nameToLayer;
if (Physics.Raycast(ray, out hit, maxDistance, layerMask))
{
var distance = hit.distance;
y = height - distance + y; // adjust
}
else
{
Debug.LogWarning("Terrain not hit, using default height !");
}
// place !
o.transform.position = new Vector3(x, y, z);
}
_extents = Extents;
_objectCount = ObjectCount;
_objectSize = ObjectSize;
}
}
The second script is attached to another empty GameObject and try to use this spawned objects from the first script:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class ShowMeshBounds : MonoBehaviour
{
public GameObject[] objectsToDraw;
public GameObject prefabEffect;
public Color color = Color.green;
private Vector3 v3FrontTopLeft;
private Vector3 v3FrontTopRight;
private Vector3 v3FrontBottomLeft;
private Vector3 v3FrontBottomRight;
private Vector3 v3BackTopLeft;
private Vector3 v3BackTopRight;
private Vector3 v3BackBottomLeft;
private Vector3 v3BackBottomRight;
private float counter = 0;
public bool animateLines;
public float speed = 1f;
private List<GameObject> allLines = new List<GameObject>();
private List<GameObject> allLinesTemp = new List<GameObject>();
private List<GameObject> instancesToMove = new List<GameObject>();
private List<GameObject> instancesToMoveTemp = new List<GameObject>();
private Vector3 endPos;
private void Start()
{
DrawObjects();
}
private void DrawObjects()
{
objectsToDraw = GameObject.FindGameObjectsWithTag("SpawnObject");
for (int i = 0; i < objectsToDraw.Length; i++)
{
CalcPositons(objectsToDraw[i]);
DrawBox();
DuplicatePrefabEffects(allLines.Count);
for (int x = 0; x < allLines.Count; x++)
{
allLinesTemp.Add(allLines[x]);
instancesToMoveTemp.Add(instancesToMove[x]);
allLines[x].transform.parent = objectsToDraw[i].transform;
instancesToMove[x].transform.parent = objectsToDraw[i].transform;
}
allLines = new List<GameObject>();
instancesToMove = new List<GameObject>();
}
StartCoroutine(moveStuff());
}
private void DuplicatePrefabEffects(int duplicationNumber)
{
for (int i = 0; i < duplicationNumber; i++)
{
var go = Instantiate(prefabEffect);
go.tag = "Duplicated Prefab";
go.name = "Duplicated Prefab";
instancesToMove.Add(go);
}
}
void CalcPositons(GameObject objectToDrawTransform)
{
Bounds bounds = objectToDrawTransform.GetComponent<MeshFilter>().sharedMesh.bounds;
Vector3 v3Center = bounds.center;
Vector3 v3Extents = bounds.extents;
v3FrontTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z); // Front top left corner
v3FrontTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z); // Front top right corner
v3FrontBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z); // Front bottom left corner
v3FrontBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z); // Front bottom right corner
v3BackTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z); // Back top left corner
v3BackTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z); // Back top right corner
v3BackBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z); // Back bottom left corner
v3BackBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z); // Back bottom right corner
v3FrontTopLeft = objectToDrawTransform.transform.TransformPoint(v3FrontTopLeft);
v3FrontTopRight = objectToDrawTransform.transform.TransformPoint(v3FrontTopRight);
v3FrontBottomLeft = objectToDrawTransform.transform.TransformPoint(v3FrontBottomLeft);
v3FrontBottomRight = objectToDrawTransform.transform.TransformPoint(v3FrontBottomRight);
v3BackTopLeft = objectToDrawTransform.transform.TransformPoint(v3BackTopLeft);
v3BackTopRight = objectToDrawTransform.transform.TransformPoint(v3BackTopRight);
v3BackBottomLeft = objectToDrawTransform.transform.TransformPoint(v3BackBottomLeft);
v3BackBottomRight = objectToDrawTransform.transform.TransformPoint(v3BackBottomRight);
}
void DrawBox()
{
SpawnLineGenerator(v3FrontTopLeft, v3FrontTopRight, color);
SpawnLineGenerator(v3FrontTopRight, v3FrontBottomRight, color);
SpawnLineGenerator(v3FrontBottomRight, v3FrontBottomLeft, color);
SpawnLineGenerator(v3FrontBottomLeft, v3FrontTopLeft, color);
SpawnLineGenerator(v3BackTopLeft, v3BackTopRight, color);
SpawnLineGenerator(v3BackTopRight, v3BackBottomRight, color);
SpawnLineGenerator(v3BackBottomRight, v3BackBottomLeft, color);
SpawnLineGenerator(v3BackBottomLeft, v3BackTopLeft, color);
SpawnLineGenerator(v3FrontTopLeft, v3BackTopLeft, color);
SpawnLineGenerator(v3FrontTopRight, v3BackTopRight, color);
SpawnLineGenerator(v3FrontBottomRight, v3BackBottomRight, color);
SpawnLineGenerator(v3FrontBottomLeft, v3BackBottomLeft, color);
}
void SpawnLineGenerator(Vector3 start, Vector3 end, Color color)
{
GameObject myLine = new GameObject();
myLine.tag = "FrameLine";
myLine.name = "FrameLine";
myLine.AddComponent<LineRenderer>();
myLine.AddComponent<EndHolder>();
myLine.GetComponent<EndHolder>().EndVector = end;
LineRenderer lr = myLine.GetComponent<LineRenderer>();
lr.material = new Material(Shader.Find("Particles/Alpha Blended Premultiply"));
lr.startColor = color;
lr.useWorldSpace = false;
lr.endColor = color;
lr.startWidth = 1f;//0.1f;//0.03f;
lr.endWidth = 1f;//0.1f;//0.03f;
lr.SetPosition(0, start);
lr.SetPosition(1, start);
allLines.Add(myLine);
}
IEnumerator moveStuff()
{
for (int i = 0; i < allLinesTemp.Count; i++)
{
counter = 0;
while (Vector3.Distance(instancesToMoveTemp[i].transform.position, endPos) > 0.1f)
{
counter++;
endPos = allLinesTemp[i].GetComponent<EndHolder>().EndVector;
Vector3 startPos = allLinesTemp[i].GetComponent<LineRenderer>().GetPosition(0);
instancesToMoveTemp[i].transform.position =
Vector3.MoveTowards(startPos, endPos, counter / 25f * speed);
allLinesTemp[i].GetComponent<LineRenderer>().SetPosition(1, instancesToMoveTemp[i].transform.position);//tempPos);
yield return null;
}
}
}
}
But since the first script is destroying the spawned objects then the second script give me the exception:
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object. ShowMeshBounds+c__Iterator0.MoveNext () (at Assets/Scripts/ShowMeshBounds.cs:145) UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
Line 145 is:
while (Vector3.Distance(instancesToMoveTemp[i].transform.position, endPos) > 0.1f)
First second or frame instancesToMove List have some items but then since the first script destroyed them then instancesToMove is still looks like with the items but they are not exist so he can't use them.
Again I'm confused. How can I use the two scripts ?
The first to create and spawn new objects and to be able to remove the objects. The second to use the objects and maybe to update somehow if thy were destroyed.
Not sure what and how to do it.
Your answer
Follow this Question
Related Questions
How can i prevent from mouse to collide with thirdpersoncontroller ? 0 Answers
How can i pick two randomly items from gameobject array ? 1 Answer
Script for a hue rainbow scroll on the material 1 Answer
How can i using a break point if a gameobject have a collider after added to it ? 1 Answer
How can i get all childs from List ? 3 Answers