簡單說一下屬性和字段的區別:字段就是成員變量,而屬性確實提供給外部訪問內部成員變量的接口。之所以會有屬性的出現,就是為了避免外部對類的成員的直接訪問,通俗的說就是OOP中的封裝思想。
using UnityEngine; using System.Collections; public class DemoTest : MonoBehaviour { private int _score; public int Score { get { return _score; } set { if (value > 100) { value = 100; } _score = value; } } }上面的示例中_score就是字段或者叫成員變量,,而Score其實是C#語法簡化的方法,提供了私有成員_score對外部的訪問接口,當我們通過Score更改_score的值時就會觸發set{…}代碼段的代碼執行,這樣就完成了對_score的范圍限制,這里就體現了OOP中的封裝的好處啦。。。。關於屬性和字段的介紹就到此為止,下面說一下這篇文章的主題。
在Unity中可以把字段使用[SerializeField]的方式序列化到Inspector面板(至於什么是序列化,讀者可以自行百度),當然public 訪問權限的字段是隱式添加[SerializeField],所以可以直接被序列化的,private的字段也可以手動添加[SerializeField]來實現序列化的比如上述的例子中我簡單在_score上添加[SerializeField],就可以在Inspector面板上直接對_score賦值了
using UnityEngine; using System.Collections; public class DemoTest : MonoBehaviour { [SerializeField] private int _score; public int Score { get { return _score; } set { if (value > 100) { value = 100; } _score = value; } } }
之所以會顯示Score,而不是_score,這是unity3d在顯示的時候做的一些處理,不必關注。然而此時我們如果直接修改Score的值到120,那么我們其實直接修改的_score的值,而不是通過屬性Score來訪問的,所以我們限定的_score<=100,就不在起作用了,那么如果在工程中有這種需求該怎么處理呢?有兩種方案可供選擇,先說第一種寫Editor的方式實現:
using UnityEngine; using System.Collections; public class DemoTest : MonoBehaviour { // [SerializeField] private int _score; public int Score { get { return _score; } set { if (value > 100) { value = 100; } print("set _score value = " + value); _score = value; } } }
自定義的Editor類源碼(當然該類必須放在Editor目錄下:
using UnityEngine; using System.Collections; using UnityEditor; [CustomEditor(typeof(DemoTest))] //為DemoTest添加一個自定義標簽 public class EditorTest : Editor { public override void OnInspectorGUI() //當DemoTest在Inspector面板上顯示改動時觸發 { DemoTest demoTest = target as DemoTest; //target是Eiditor內部封裝的當前操作的對象引用 int score = EditorGUILayout.IntField("Score", demoTest.Score);//在Inspector面板上序列化一個對象,並關聯demoTest.Score屬性 if (demoTest.Score != score)//如果該屬性在改動后沒有觸發就手動觸發 { demoTest.Score = score; } base.DrawDefaultInspector();//重回Inspector面板 } }
這樣當我們修改Socre時就可以在Console中看到相應的輸出了,也就解決了set、get方法封裝性問題。當然這種方式很有局限性,使用起來十分不方便,還有一種簡便的方式,使用SetProperty標簽,當然我個人由於unity版本過低,
SetProperty還不支持,,應該要5.0以后的版本吧,這里附上鏈接:https://github.com/LMNRY/SetProperty