0

In the first script i clone some GameObjects:

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

public class CloneObjects : MonoBehaviour
{
    public GameObject ObjectToCreate;
    public int objectsHeight = 3;
    [HideInInspector]
    public GameObject[] objects;

    // for tracking properties change
    private Vector3 _extents;
    private int _objectCount;
    private float _objectSize;
    private List<GameObject> cloneList = new List<GameObject>();

    /// <summary>
    ///     How far to place spheres randomly.
    /// </summary>
    public Vector3 Extents;

    /// <summary>
    ///     How many spheres wanted.
    /// </summary>
    public int ObjectCount;
    public float ObjectSize;

    public static float LargestSize = 0;

    // Use this for initialization
    void Start()
    {
        Clone();
        //objects = GameObject.FindGameObjectsWithTag("ClonedObject");
        objects = cloneList.ToArray();
        foreach (var element in objects)
        {
            float Size = element.transform.localScale.x;
            if (Size > LargestSize)
                LargestSize = Size;
        }
    }

    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;
    }

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

    }

    private void Clone()
    {
        if (Extents == _extents && ObjectCount == _objectCount && Mathf.Approximately(ObjectSize, _objectSize))
            return;

        // cleanup
        //var ObjectsToDestroy = GameObject.FindGameObjectsWithTag("ClonedObject");
        var ObjectsToDestroy = objects;
        foreach (var t in ObjectsToDestroy)
        {
            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(ObjectToCreate);
            cloneList.Add(o);
            o.transform.SetParent(base.gameObject.transform);
            o.transform.localScale = new Vector3(ObjectSize, ObjectSize, ObjectSize);

            // get random position
            var x = Random.Range(-Extents.x, Extents.x);
            var 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.GetMask("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 + objectsHeight, z);
        }
        _extents = Extents;
        _objectCount = ObjectCount;
        _objectSize = ObjectSize;
    }
}

Before in the first time i used to give the children objects i clone a Tag name. So i could do:

var ObjectsToDestroy = GameObject.FindGameObjectsWithTag("ClonedObject");

But now i'm not using this line. So all the cloned objects are untagged. So now i'm not using this line.

But now i want to get all the cloned objects from another script:

void Start()
    {
        anims = GetComponent<Animations>();
        waypoints = GameObject.FindGameObjectsWithTag("ClonedObject");
        originalPosition = transform.position;
    }

But since the cloned onjects are without any tag waypoints will be empty. waypoints is array of GameObject: GameObject[] waypoints.

Should i give tag name to every cloned object ? Or is there any other way to get all the cloned objects into array/List ?

2 Answers 2

1

Solution A

Make your cloneList public or create a public property that returns it, then access it from another script.

public class CloneObjects : MonoBehaviour
{
    public List<GameObject> cloneList = new List<GameObject>();
}

public class AnotherScript : MonoBehaviour
{
    void Start()
    {
        var cloneObjects = obj_with_CloneObjects.GetComponent<CloneObjects>();
        //cloneObjects.cloneList 
    }
}

Solution B

Create a field of type List<GameObject> in another script. After cloning, assign the cloneList to that field.

public class CloneObjects : MonoBehaviour
{
    public List<GameObject> cloneList = new List<GameObject>();

    void Clone()
    {
    }

    void Start()
    {
        Clone();
        obj_with_AnotherScript.GetComponent<AnotherScript>.cloneList = cloneList;
    }
}

public class AnotherScript : MonoBehaviour
{
    public List<GameObject> cloneList = new List<GameObject>();

    void Start()
    {
        //this.cloneList 
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

But since the cloned onjects are without any tag waypoints will be empty. waypoints is array of GameObject: GameObject[] waypoints.

You can change the tag of the GameObject after instantiating it.

var o = Instantiate(ObjectToCreate);
o.tag = "ClonedObject";

Just make sure that you create a tag called "ClonedObject" in the Editor. Now, GameObject.FindGameObjectsWithTag("ClonedObject"); should return something if there are instantiated Objects with that tag name.

Should I give tag name to every cloned object ? Or is there any other way to get all the cloned objects into array/List ?

Using tag with FindGameObjectsWithTag should do fine. If you care about performance then then use List since FindGameObjectsWithTag will search for for GameObjects with that tag. It is is slower.

I noticed that you are already storing instantiated GameObjects in a List.

Change

private List<GameObject> cloneList = new List<GameObject>();

to

public List<GameObject> cloneList = new List<GameObject>();

If there is only one instance of CloneObjects script in your scene, you can use FindObjectOfType to find the CloneObjects script then access the cloneList variable.

CloneObjects cloneObjectsInstance = FindObjectOfType<CloneObjects>();
List<GameObject> clonedObj = cloneObjectsInstance.cloneList;
for (int i = 0; i < clonedObj.Count; i++)
{

}

If there are more than one instance of CloneObjects script in your scene, Find the GameObject that script is attached to then perform GetComponent on it.

CloneObjects  cloneObjectsInstance = GameObject.Find("ObjectCloneObjectsIsAttachedTO").GetComponent<CloneObjects>();
List<GameObject> clonedObj = cloneObjectsInstance.cloneList;
for (int i = 0; i < clonedObj.Count; i++)
{

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.