Unity中ScreenState结构体成员变量仅在函数作用域生效的问题
问题分析与解决方案
问题根源
你遇到的核心问题是**ScreenState被定义为struct(值类型)。在C#中,值类型存储的是实际数据,当你从字典_childStates或_states中获取ScreenState实例时,会返回一个副本**。调用ChangeChildState方法时,你修改的是这个副本的_currentChild字段,而字典中存储的原实例的_currentChild完全没变化。这就是为什么Debug时看到函数内值变了,但后续读取还是初始值的原因。
解决方案
把ScreenState从struct改为class(引用类型)。引用类型存储的是对象的引用,字典中保存的是引用地址,调用方法时操作的是同一个对象实例,修改_currentChild会直接作用在原实例上,不会出现副本问题。
修改后的代码如下:
class ScreenState // 此处将struct改为class { public string name; public GameObject state; private Dictionary<string, ScreenState> _childStates; private string _currentChild; public ScreenState(GameObject fab) { name = fab.name; state = Instantiate(fab) as GameObject; state.transform.position = new Vector3(100, 100, 100); _childStates = new Dictionary<string, ScreenState>(); GameObject[] children = fab.GetComponent<ChildStates>().childFABs; for (int ch = 0; ch < children.Length; ch++) _childStates.Add(children[ch].name, new ScreenState(children[ch])); if (_childStates.Count > 0) _currentChild = _childStates.ElementAt(0).Key; else _currentChild = null; } public void EnableState() { state.transform.position = new Vector3(-5, 2, -20); if (_currentChild != null) _childStates[_currentChild].EnableState(); } public void DisableState() { state.transform.position = new Vector3(100, 100, 100); if (_currentChild != null) _childStates[_currentChild].DisableState(); } public void ChangeChildState(string stt) { _childStates[_currentChild].DisableState(); _childStates[stt].EnableState(); _currentChild = stt; } }
额外说明
- 改为
class后,所有原有逻辑无需调整,构造函数、方法的调用方式完全一致。 - 如果原本使用
struct是为了值语义的特性(比如赋值时复制全量数据),那需要重新评估,但你的场景明显需要共享状态的引用语义,所以改为class是完全适配的。
内容的提问来源于stack exchange,提问作者Circlesho
相关产品推荐
相关产品推荐

