Unity 2020如何忽略列表中缺失元素 或是移除已销毁的目标对象
问题原因
固定长度的GameObject数组不会自动清理已销毁对象的引用,访问Destroy后的对象元素时会触发空引用异常,导致程序卡住。
方案1:移除已销毁目标(推荐)
将数组替换为可变长度的List<GameObject>,每次操作前清理无效引用,适配对象动态销毁的场景:
using System.Collections.Generic; // 需引入命名空间 using UnityEngine; public class SkinMananger : MonoBehaviour { public List<GameObject> characters = new List<GameObject>(); // 替换数组为List public int selectedCharacter = 0; public GameObject carrot; // 新增方法:清理已销毁的角色引用 private void CleanupDestroyedCharacters() { // 移除所有为空的元素 characters.RemoveAll(character => character == null); // 修正选中索引避免越界 if (characters.Count == 0) selectedCharacter = 0; else if (selectedCharacter >= characters.Count) selectedCharacter = characters.Count - 1; } public void NextOption() { CleanupDestroyedCharacters(); if (characters.Count == 0) return; // 没有可用角色直接返回 characters[selectedCharacter].SetActive(false); selectedCharacter = (selectedCharacter + 1) % characters.Count; characters[selectedCharacter].SetActive(true); } public void BackOption() { CleanupDestroyedCharacters(); if (characters.Count == 0) return; characters[selectedCharacter].SetActive(false); selectedCharacter--; if(selectedCharacter < 0) { selectedCharacter += characters.Count; } characters[selectedCharacter].SetActive(true); } public void PlayGame() { // 原代码逻辑错误,GetInt是读取,存储用SetInt PlayerPrefs.SetInt("selectedCharacter", selectedCharacter); PlayerPrefs.Save(); // 可选,立即持久化存储 } }
你需要在Inspector面板重新给characters列表赋值原有角色对象即可。
方案2:仅忽略缺失元素
如果不想改动原有数组结构,每次访问元素前加非空判断即可:
public void NextOption() { // 跳过已销毁的当前选中角色 while (selectedCharacter < characters.Length && characters[selectedCharacter] == null) { selectedCharacter = (selectedCharacter + 1) % characters.Length; } if (selectedCharacter >= characters.Length) return; characters[selectedCharacter].SetActive(false); // 找下一个存在的角色 int next = (selectedCharacter + 1) % characters.Length; while (next != selectedCharacter && characters[next] == null) { next = (next + 1) % characters.Length; } if (next == selectedCharacter) return; // 没有可用角色 selectedCharacter = next; characters[selectedCharacter].SetActive(true); } // BackOption方法同理加非空判断即可
其他注意事项
原有PlayGame方法中误用了PlayerPrefs.GetInt,该接口是读取存储值,保存选中角色需要使用PlayerPrefs.SetInt,已在方案1代码中修正。
内容的提问来源于stack exchange,提问作者user706499
相关产品推荐
相关产品推荐

