Unity中同标签砖块(tugla)位置更新异常问题求助
问题
我正在用Unity开发一款简单的移动端游戏,尝试修改标签为tugla的砖块位置。需求是:当球击中砖块后,待球触碰地面时更新砖块位置;球触碰砖块时会销毁砖块。目前未击中砖块时功能正常,但击中第二个或其他砖块后,部分砖块无法更新位置——例如游戏中有4个砖块,击中第二个后,仅第三、第四个砖块会移动到新位置。
砖块代码(tugla.cs)
public class tugla : MonoBehaviour { public static int toplamTuglaSayisi; public Sprite[] tuglaSprite; private int maxCarpmaSayisi; private int carpmaSayisi; GameObject kirmizitop; void Start() { maxCarpmaSayisi = tuglaSprite.Length + 1; toplamTuglaSayisi++; kirmizitop = GameObject.FindGameObjectWithTag("kirmizitop"); } void Update() { // -1.330 -1.868 } private void OnTriggerEnter2D(Collider2D collision) { Debug.Log("kirmizi top geçti"); carpmaSayisi++; if (carpmaSayisi >= maxCarpmaSayisi) { toplamTuglaSayisi--; if (toplamTuglaSayisi <= 0) { Debug.Log("works"); GameObject.FindObjectOfType<OyunKontrol>().GetComponent<OyunKontrol>().birsonrakisahne(); } Destroy(gameObject); } else { GetComponent<SpriteRenderer>().sprite = tuglaSprite[carpmaSayisi - 1]; } } private void OnCollisionEnter2D(Collision2D collision) { if (collision.gameObject.name.Equals("top")) { carpmaSayisi++; if (carpmaSayisi >= maxCarpmaSayisi) { toplamTuglaSayisi--; if(toplamTuglaSayisi <= 0) { Debug.Log("works"); GameObject.FindObjectOfType<OyunKontrol>().GetComponent<OyunKontrol>().birsonrakisahne(); } Destroy(gameObject); } else { GetComponent<SpriteRenderer>().sprite = tuglaSprite[carpmaSayisi - 1]; } } } }
球的代码(top.cs)
public class top : MonoBehaviour { GameObject topataci; Rigidbody2D fizik; GameObject acigostergesi; GameObject[] tugla; public GameObject top_arka; void Start() { fizik = GetComponent<Rigidbody2D>(); topataci = GameObject.FindGameObjectWithTag("topataci"); acigostergesi = GameObject.FindGameObjectWithTag("acigostergesi"); tugla = GameObject.FindGameObjectsWithTag("tugla"); } void Update() { // 注释代码省略 } void OnCollisionEnter2D(Collision2D Collider) { if (Collider.gameObject.name.Equals("zemin")) { GetComponent<Rigidbody2D>().velocity = new Vector2(0f, 0f); topataci.GetComponent<Transform>().transform.position = new Vector3(0, -6.04f, 0); acigostergesi.GetComponent<Transform>().transform.position = new Vector3(transform.position.x, transform.position.y, 10f); acigostergesi.GetComponent<Rigidbody2D>().rotation = 0; if (tugla.Length <= 0) { // SceneManager.LoadScene(1); } else { for (int i = 0; i < tugla.Length; i++) { Debug.Log("Getting new position"); tugla[i].GetComponent<Transform>().transform.position += Vector3.down * 0.538f; } } } } }
问题原因
核心问题在于球脚本中的tugla数组只在Start()方法中初始化一次。当砖块被销毁后,数组里依然保留着这些已销毁对象的引用——这些引用不会自动从数组中移除,导致遍历数组时,已销毁的砖块对象无法执行移动操作,而你看到的“仅第三、第四个砖块移动”是因为数组中后面的元素还存活。
修复方案
1. 每次触地时重新获取存活的砖块
移除Start()中初始化tugla数组的代码,改为在球触碰地面时,实时查找所有标签为tugla的存活对象,确保数组里只包含当前存在的砖块。
2. 增加对象有效性判断
遍历数组时,先检查对象是否为null(避免已销毁对象引发的问题),再执行移动操作。
修改后的球脚本(top.cs)
public class top : MonoBehaviour { GameObject topataci; Rigidbody2D fizik; GameObject acigostergesi; public GameObject top_arka; void Start() { fizik = GetComponent<Rigidbody2D>(); topataci = GameObject.FindGameObjectWithTag("topataci"); acigostergesi = GameObject.FindGameObjectWithTag("acigostergesi"); } void Update() { // 注释代码省略 } void OnCollisionEnter2D(Collision2D Collider) { if (Collider.gameObject.name.Equals("zemin")) { GetComponent<Rigidbody2D>().velocity = new Vector2(0f, 0f); topataci.transform.position = new Vector3(0, -6.04f, 0); acigostergesi.transform.position = new Vector3(transform.position.x, transform.position.y, 10f); acigostergesi.GetComponent<Rigidbody2D>().rotation = 0; // 实时获取当前所有存活的tugla砖块 GameObject[] tugla = GameObject.FindGameObjectsWithTag("tugla"); if (tugla.Length > 0) { for (int i = 0; i < tugla.Length; i++) { // 确保对象未被销毁 if(tugla[i] != null) { Debug.Log("Getting new position"); tugla[i].transform.position += Vector3.down * 0.538f; } } } else { // SceneManager.LoadScene(1); } } } }
额外优化:Unity中每个GameObject都自带transform属性,无需调用GetComponent<Transform>(),可以直接使用obj.transform简化代码。
内容的提问来源于stack exchange,提问作者Berkay Isıkoglu
相关产品推荐
相关产品推荐

