2017-02-20 69 views
-2

我在理解C#中的属性如何工作时遇到了一些麻烦。首先介绍一下背景知识:我在统一级别管理器上工作,其目的是包含每个级别的游戏级别和信息列表(级别描述,级别图像等),所有这些都保存在一个ScriptableObject中。C#遇到属性变量问题(获取并设置)

因此,让我说我有3个属性,sceneIndex,sceneName和LevelID。

sceneIndex是一个变量,我应该能够在unity的检查器中进行更改,并且应该在构建设置中匹配级别索引。

sceneName不应该在团结督察中编辑,并且应该始终是关卡的名称。 (这是由sceneIndex确定的)

LevelID应始终设置为级别列表中此类的索引。

这是我当前的代码 - 当前当我更改sceneIndex时,我的sceneName未更新为检查器中的匹配名称,并且当我向列表中添加新元素时,LevelID未更新。

public class LevelDataBase : ScriptableObject { 

    [System.Serializable] 
    public class LevelData { 

     [SerializeField] 
     public string p_sceneName{//the levelName 
      get{ return sceneName; } 
      set{ sceneName = SceneManager.GetSceneAt (sceneIndex).name; }// it should always be set depending on the Scene Index 
     } 
     public string sceneName;//Properties dont display in unity's inspector so i have to use secondary variable for it to be displayed. 

     public int sceneIndex;//the scene index i should be able to change and then the scene Name should Updatedepending on the value 


     [SerializeField] 
     public int p_LevelID {//the Level id Should always be the index of this class in the list. 
      get{ return LevelID; } 
      set{ LevelID = LevelList.IndexOf (this); } 
     } 
     public int LevelID; 

     public string DisplayName; 
     public Sprite Image; 
     public string Description; 
    } 

    public List<LevelData> LevelList;//this is a list containing all the levels in the game 
} 

谢谢〜斯科特

+2

“不工作” - 是不是一个正确的描述。 –

回答

1

看来你是误会性质的工作方式。您使用set{ sceneName = SceneManager.GetSceneAt (sceneIndex).name; }就好像它会描述它应该工作的方式(某种基于属性的开发)。

属性用于封装字段。因此他们提供了一种“获取”和“设置”功能。设置的功能只有在使用MyProperty = value时才会被调用; get属性将由value = MyProperty触发。

所以感觉你的套件应该在get中重命名,你应该摆脱你以前的得到。

public string SceneName{//the levelName 
      get{ return SceneManager.GetSceneAt (sceneIndex).name; }// it should always be set depending on the Scene Index 
     } 

然后在你的代码,你应该总是使用访问SceneName而非公共字符串sceneName这个数据(也就是现在的可能没用)。

编辑:使用二传手:

public int SceneIndex{ 
    set 
    { 
     sceneIndex = value; 
     sceneName= SceneManager.GetSceneAt (sceneIndex).name; }// it should always be set depending on the Scene Index 
    } 
} 
+0

嘿布鲁诺感谢他们回复。是误解了属性如何工作,所以感谢解释。但是我必须使用“公共字符串sceneName”变量的原因是因为在unity的检查器中显示的不正确。这就是为什么即时通讯使用第二个变量,并在属性被改变时改变它。 – WeirderChimp53

+0

我不习惯统一,但对我来说,属性被忽略似乎很危险。无论如何,你可以做的是使用setter来修改sceneIndex,它也会更新sceneName。我更新了我的答案以反映这一点。 –

+0

所以我搞砸了,并实现了你的代码片段。现在是工作,如果我在运行时调用“SceneIndex = 1;” sceneIndex和sceneName被更新。唯一的问题是,因为im在unity的检查器中改变sceneIndex(variable not property)属性值永远不会被改变,因此不会调用“set”而不会更新sceneName。 – WeirderChimp53