2017-04-07 61 views
0

在第一个脚本我克隆一些GameObjects:如何在不使用FindGameObjectsWithTag的情况下获取特定的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; 
    } 
} 

在第一时间我用来给孩子们反对我克隆一个标签名称之前。 所以我可以做的:

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

但我现在没有使用这条线。所以所有克隆的对象都是未标记的。 所以现在我不使用这条线。

但现在我想从另一个脚本中的所有克隆的对象:

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

但由于克隆onjects是没有任何标记的航点是空的。 waypoints是GameObject:GameObject []航点的数组。

我应该给每个克隆对象的标签名称?或者有没有其他方法可以将所有克隆的对象放入数组/列表中?

回答

1

解决方案A

让您cloneList公共或创建返回它的公共属性,然后从另一个脚本访问。

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

溶液B

在另一个脚本创建List<GameObject>类型的字段。克隆后,将cloneList分配到该字段。

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

但由于克隆onjects是没有任何标记的航点将会 空。航点是GameObject:GameObject []航点的数组。

您可以在实例化之后更改GameObject的标签。

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

只要确保你在 编辑器创建一个名为“ClonedObject”标签。现在,GameObject.FindGameObjectsWithTag("ClonedObject");应该返回一些东西,如果有标签名称的实例化对象。

我应该给每个克隆对象赋予标签名吗?或者是否有任何其他 的方式来获取所有克隆的对象到数组/列表?

FindGameObjectsWithTag使用标记应该没问题。如果您关心性能,那么请使用List,因为FindGameObjectsWithTag将搜索具有该标签的GameObjects。这是慢的。

我注意到你已经在List中存储了实例化的GameObjects。

变化

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

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

如果只有比如在你的场景CloneObjects一个脚本,您可以使用FindObjectOfType找到那么CloneObjects脚本访问cloneList变量。

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

} 

如果在你的场景CloneObjects脚本的多个实例,查找游戏对象该脚本连接到然后在其上进行GetComponent

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

} 
相关问题