Unity Remote 5运行正常但Android打包后仅生成1个Tile的问题
Unity Android打包后Tile生成异常问题排查与解决
问题现象
- Unity编辑器、Unity Remote 5环境:屏幕两侧可正常各生成40个Tile
- Android打包后:仅一侧生成1个Tile即停止运行
- 已尝试操作:新建场景测试、将脚本从主相机移至空GameObject,问题未解决
相关代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Matchager : MonoBehaviour { SpriteRenderer spr1; SpriteRenderer spr2; [SerializeField] Sprite[] sprotes; [SerializeField] GameObject[] Endres; [SerializeField] GameObject[] All; [SerializeField] GameObject Fold1; [SerializeField] GameObject Fold2; [SerializeField] GameObject note1; [SerializeField] GameObject note2; [SerializeField] GameObject note3; public static GameObject currentnote; public static GameObject currentnote2; public static bool notpressable; public static bool notpressable2; public static bool corunner; public static bool corunner2; bool runnow; private void Start() { spr1 = Endres[5].GetComponent<SpriteRenderer>(); spr2 = Endres[6].GetComponent<SpriteRenderer>(); Invoke("Waiter", 2f); } private void Update() { if (Fold1.transform.childCount == 0 && runnow) bottomwin(); else if (Fold2.transform.childCount == 0 && runnow) topwin(); } private GameObject GetRandomNote() { int randomIndex = Random.Range(0, 3); switch (randomIndex) { case 0: return note1; case 1: return note2; case 2: return note3; default: return null; } } void Waiter() { for (int i = 0; i < 40; i++) { Vector3Int tilePosition = new Vector3Int(0 + (i * 5), -2, 0); GameObject tam = Instantiate(GetRandomNote(), Fold1.transform); GameObject tam2 = Instantiate(tam, Fold2.transform); tam.transform.position = tilePosition; tam2.transform.position = -tilePosition; if (tam.GetComponent<Matchotes>().Uni == 1) tam2.GetComponent<Matchotes>().Uni = 4; else if (tam.GetComponent<Matchotes>().Uni == 2) tam2.GetComponent<Matchotes>().Uni = 5; else if (tam.GetComponent<Matchotes>().Uni == 3) tam2.GetComponent<Matchotes>().Uni = 6; } runnow = true; } void topwin() { Fold1.SetActive(false); Fold2.SetActive(false); foreach (GameObject game in All) game.SetActive(false); Endres[0].SetActive(true); Endres[1].SetActive(true); Endres[4].SetActive(true); Endres[7].SetActive(true); Endres[8].SetActive(true); RectTransform rect = Endres[2].GetComponent<RectTransform>(); RectTransform rect2 = Endres[3].GetComponent<RectTransform>(); rect.anchoredPosition = new Vector2(rect.anchoredPosition.x, 100); rect.localRotation = Quaternion.Euler(rect.localRotation.x, rect.localRotation.x, 180); rect2.anchoredPosition = new Vector2(rect.anchoredPosition.x, -100); spr1.sprite = sprotes[0]; spr2.sprite = sprotes[1]; } void bottomwin() { Fold1.SetActive(false); Fold2.SetActive(false); foreach (GameObject game in All) game.SetActive(false); Endres[0].SetActive(true); Endres[1].SetActive(true); Endres[4].SetActive(true); Endres[7].SetActive(true); Endres[8].SetActive(true); RectTransform rect = Endres[2].GetComponent<RectTransform>(); RectTransform rect2 = Endres[3].GetComponent<RectTransform>(); rect.anchoredPosition = new Vector2(rect.anchoredPosition.x, -100); rect2.localRotation = Quaternion.Euler(rect.localRotation.x, rect.localRotation.x, 180); rect2.anchoredPosition = new Vector2(rect.anchoredPosition.x, 100); spr1.sprite = sprotes[2]; spr2.sprite = sprotes[3]; } }
排查与修复方案
1. 主线程阻塞导致中断
Waiter方法在主线程一次性实例化80个对象,Android设备性能不足时会触发卡顿甚至中断执行。
修复:改用协程分步实例化
替换Start和Waiter方法:
private void Start() { spr1 = Endres[5].GetComponent<SpriteRenderer>(); spr2 = Endres[6].GetComponent<SpriteRenderer>(); StartCoroutine(WaiterCoroutine()); } IEnumerator WaiterCoroutine() { yield return new WaitForSeconds(2f); for (int i = 0; i < 40; i++) { Vector3 tilePosition = new Vector3(0 + (i * 5f), -2f, 0f); GameObject tam = Instantiate(GetRandomNote(), Fold1.transform); GameObject tam2 = Instantiate(tam, Fold2.transform); tam.transform.position = tilePosition; tam2.transform.position = -tilePosition; Matchotes tamMatch = tam.GetComponent<Matchotes>(); Matchotes tam2Match = tam2.GetComponent<Matchotes>(); if (tamMatch != null && tam2Match != null) { if (tamMatch.Uni == 1) tam2Match.Uni = 4; else if (tamMatch.Uni == 2) tam2Match.Uni = 5; else if (tamMatch.Uni == 3) tam2Match.Uni = 6; } // 每实例化5个暂停一帧,避免阻塞主线程 if (i % 5 == 0) yield return null; } runnow = true; }
2. 空引用异常中断循环
若note1/note2/note3预制体未挂载Matchotes组件,Android平台加载时会触发空引用异常,终止循环。
修复:
- 检查三个note预制体,确保都挂载
Matchotes组件 - 添加空引用判断(如上代码所示),避免异常崩溃
3. 坐标精度问题
Vector3Int在Android平台可能出现精度丢失,导致后续Tile被渲染到视口外,看起来像停止生成。
修复:改用Vector3浮点类型设置坐标(已包含在协程修复代码中)
4. 渲染层级问题
后续生成的Tile可能超出相机裁剪范围或被遮挡,导致不可见。
修复:
- 调整相机裁剪面参数,确保覆盖所有Tile的坐标范围
- 给Tile添加高辨识度颜色,验证是否实际生成但未显示
内容的提问来源于stack exchange,提问作者TFO Society
相关产品推荐
相关产品推荐

