Unity中C#数组初始化错误CS0847及索引越界问题求助
问题解决与代码修正
1. 解决编译报错error CS0847
报错原因:声明了长度为120的字符串数组,但初始化时提供的元素数量不足120,编译器要求数组初始化器的元素数量必须和指定长度完全匹配。
修正方案:去掉数组声明中的硬编码长度[120],让编译器自动推断数组长度,避免长度与实际元素数量不匹配的问题:
public string[] groups = { "hydrogenScreen" , "heliumScreen", "menu", "li", "be", "b", "c", "n", "o", "f", "ne", "na", "mg", "al", "si", "p", "s", "cl", "ar", "k", "ca","sc", "ti","v", "cr","mn","fe","co", "ni", "cu", "zn", "ga", "ge", "as", "se", "br", "kr", "rb", "sr", "y" , "zr", "nb", "mo", "tc", "ru" , "rh", "pd", "ag", "cd", "in" , "sn", "sb" , "te", "i", "xe", "cs", "ba", "la", "ce", "pr", "nd", "pm", "sm", "eu", "gd", "tb", "dy", "ho", "er", "tm", "yb", "hf", "ta", "w", "re", "os", "ir", "pt", "au", "hg", "tl", "pb", "bi", "po", "at", "rn", "fr", "ra", "ac", "th", "pa", "u", "np", "pu", "am", "cm", "bk", "cf", "es", "fm", "md", "no", "lr", "rf", "db", "sg", "bh", "hs", "mt", "ds", "rg", "cn", "nh", "fl", "mc", "lv", "ts", "og" };
2. 解决索引越界错误
索引越界的核心问题:
- 方法参数
string groups和类成员数组groups重名,导致方法内误将字符串参数当作数组访问,groups[n]本质是取字符串的单个字符索引,当n超出字符串长度时触发越界; - 循环条件硬编码
n < 119,未绑定实际数组长度,数组元素数量变化后极易出现越界; - 原逻辑循环中每次对比都执行激活/失活,最终仅保留最后一次循环结果,逻辑完全错误。
修正方案:
- 重命名方法参数避免冲突,比如改为
string targetGroupName; - 循环使用数组
Length属性作为边界,确保不超索引范围; - 优化逻辑:先失活所有标签,再找到匹配标签激活。
修正后的完整代码
using System; using System.Linq; using UnityEngine; using UnityEngine.UI; public class TabController : MonoBehaviour { // 自动推断数组长度,避免长度不匹配问题 public string[] groups = { "hydrogenScreen" , "heliumScreen", "menu", "li", "be", "b", "c", "n", "o", "f", "ne", "na", "mg", "al", "si", "p", "s", "cl", "ar", "k", "ca","sc", "ti","v", "cr","mn","fe","co", "ni", "cu", "zn", "ga", "ge", "as", "se", "br", "kr", "rb", "sr", "y" , "zr", "nb", "mo", "tc", "ru" , "rh", "pd", "ag", "cd", "in" , "sn", "sb" , "te", "i", "xe", "cs", "ba", "la", "ce", "pr", "nd", "pm", "sm", "eu", "gd", "tb", "dy", "ho", "er", "tm", "yb", "hf", "ta", "w", "re", "os", "ir", "pt", "au", "hg", "tl", "pb", "bi", "po", "at", "rn", "fr", "ra", "ac", "th", "pa", "u", "np", "pu", "am", "cm", "bk", "cf", "es", "fm", "md", "no", "lr", "rf", "db", "sg", "bh", "hs", "mt", "ds", "rg", "cn", "nh", "fl", "mc", "lv", "ts", "og" }; // 存储所有标签的CanvasGroup,可手动赋值或通过FindObjectsOfType获取 public CanvasGroup[] allTabGroups; public void efficientTabChange(CanvasGroup clickedGroup, string targetGroupName) { // 先失活所有标签 foreach (var group in allTabGroups) { DeactivateTabs(group); } // 找到目标标签并激活 var targetGroup = allTabGroups.FirstOrDefault(g => g.name == targetGroupName); if (targetGroup != null) { ActivateTabs(targetGroup); } } // 激活标签的逻辑 private void ActivateTabs(CanvasGroup group) { group.alpha = 1; group.interactable = true; group.blocksRaycasts = true; } // 失活标签的逻辑 private void DeactivateTabs(CanvasGroup group) { group.alpha = 0; group.interactable = false; group.blocksRaycasts = false; } }
额外优化建议
- 不要用
group.ToString()获取标签名称,CanvasGroup的ToString()返回的是对象类型信息,应直接用group.name获取组件名称; - 可提前用字典建立名称与CanvasGroup的映射,提升查找性能:
后续查找时直接用private Dictionary<string, CanvasGroup> tabMap; void Awake() { tabMap = allTabGroups.ToDictionary(g => g.name, g => g); }tabMap.TryGetValue(targetGroupName, out var targetGroup)即可。
内容的提问来源于stack exchange,提问作者Kārlis Kauliņš
相关产品推荐
相关产品推荐

