Unity 2D等距地面生成运行时改边长>9层级异常求助
问题分析与解决方案
核心问题出在deleteField方法的实现逻辑上:当你在循环中销毁子物体时,_groundContainer.transform.childCount会实时减少,导致循环只能销毁一半的旧地面块。剩余未销毁的旧块和新生成的块重叠,就会出现你看到的层级异常。而运行前设置边长时,场景中没有旧物体,因此不会触发这个问题。
另外,等距视角的地面块需要正确设置渲染顺序,否则即使销毁逻辑正确,也可能出现层级错乱。
修复步骤
1. 修正deleteField方法
将循环改为倒序遍历,避免因子物体数量实时变化导致的销毁遗漏:
void deleteField() { // 倒序遍历,确保所有子物体都被销毁 for(int i = _groundContainer.transform.childCount - 1; i >= 0; i--) { Destroy(_groundContainer.transform.GetChild(i).gameObject); } }
或者先收集所有子物体再批量销毁:
void deleteField() { List<GameObject> children = new List<GameObject>(); foreach(Transform child in _groundContainer.transform) { children.Add(child.gameObject); } foreach(GameObject child in children) { Destroy(child); } }
2. 优化等距块的渲染顺序(推荐)
等距视角中,地面块的渲染顺序应由i+j的值决定(值越大的块越靠后,需要被前面的块遮挡)。你可以通过设置Sprite的Sorting Order或调整Z轴实现:
void createField(Vector3 offset) { for(int i=1; i<= lungime; i++) { for (int j = 1; j <= lungime; j++) { Vector3 pos = new Vector3((i-j), -(i + j) / 2f, 0) + offset; GameObject newSprite = Instantiate(_sprite, pos, _sprite.transform.rotation); newSprite.transform.parent = _groundContainer.transform; newSprite.name = "ground("+i+","+j+")"; // 设置Sorting Order:i+j越大,排序值越小,确保靠后的块在底层 SpriteRenderer renderer = newSprite.GetComponent<SpriteRenderer>(); if(renderer != null) { renderer.sortingOrder = -(i + j); } // 也可以调整Z轴:让i+j大的块Z值更大(离相机更远) // newSprite.transform.position = new Vector3(pos.x, pos.y, -(i + j) * 0.01f); } } }
3. 补充边界检查(可选)
在Update中修改边长时,添加边界检查避免无效值:
private void Update() { if (lastLungime != lungime) { // 确保边长不小于1 lungime = Mathf.Max(lungime, 1); deleteField(); _width = lungime; setCameraResolution(); createField(new Vector3(0, _height, 0)); lastLungime = lungime; } }
验证
修改后,运行时调整边长为两位数,旧地面块会被完全销毁,新生成的块按正确顺序渲染,层级异常问题即可解决。
内容的提问来源于stack exchange,提问作者Loukas
相关产品推荐
相关产品推荐

