2017-04-07 60 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++) 
{ 

} 
相關問題