void OnClick() { Debug.Log("onclick"); }
這些都是你們很經常使用的事件,因此就不一一解釋了!有哪些事件咱們能夠調用,這個問題解決了。 html
接下來看,附加到對象上的腳本中的事件(以上所列出的事件)是如何被執行的?接下來咱們就來看下UICamera是如何對這些事件進行處理的! app
在UICamera裏面最早執行的就是Awake方法,因此咱們先從Awake方法看起: ide
能夠看出Awake方法主要的功能就是判斷設備類型,從而肯定你是使用的是鼠標仍是觸摸方式,但咱們一般都是用電腦去設計遊戲,因此以上的判斷都沒有被執行,而useMouse和useTouch字段默認都爲true,因此這兩個字段的值不變,接下來看Update方法(Start方法沒什麼好說的),當執行到update中的一段代碼時,以下: ui
// Process touch events first
if (useTouch) ProcessTouches();
else if (useMouse) ProcessMouse();
由於useTouch爲true,因此程序回去執行 ProcessTouches方法,這個方法主要是對觸屏事件方法的響應,轉到ProcessTouches方法,運行到這句話:for (int i = 0; i < Input.touchCount; ++i),這句話Input.touchCount爲0,由於咱們操做電腦只能經過鼠標,根本不存在觸屏操做,因此Input.touchCount爲0,程序繼續執行下面的 spa
if (Input.touchCount == 0) {
if (useMouse) ProcessMouse();
#if UNITY_EDITOR
else ProcessFakeTouches();
#endif
}
若是沒有觸屏事件,那麼就會去執行鼠標事件,也就是去執行ProcessMouse方法去,轉到ProcessMouse方法,裏面有這麼一段代碼: 設計
bool isPressed = false;
bool justPressed = false;
for (int i = 0; i < 3; ++i) {
if (Input.GetMouseButtonDown(i)) { currentScheme = ControlScheme.Mouse; justPressed = true; isPressed = true; }
else if (Input.GetMouseButton(i)) { currentScheme = ControlScheme.Mouse; isPressed = true; } }
// No need to perform raycasts every frame
if (isPressed || posChanged || mNextRaycast < RealTime.time) { mNextRaycast = RealTime.time + 0.02f;
if (!Raycast(Input.mousePosition)) hoveredObject = fallThrough;
if (hoveredObject == null) hoveredObject = genericEventHandler;
for (int i = 0; i < 3; ++i) mMouse[i].current = hoveredObject; }
當咱們點擊按鈕時,isPressed就會爲true,而mNextRaycast 永遠<RealTime.time,因此內部的代碼一直會被執行,也就是說一直執行裏面的Raycast方法(即咱們所知的發射線),轉到Raycast方法去,在Raycast方法裏面,他會判斷你當前選擇的EventType,有兩種選擇:World 表示按被擊中點的距離排序執行一個物理射線,UI表示按部件深度排序執行一個物理射線,一般咱們選擇的是UI,由於對象的層次咱們一般是按depth來設計的,在 i f (cam.eventType == EventType.UI) 裏面他會執行Physics.RaycastAll ,也就是發出射線,並把擊中的對象賦給hoveredObject(hoveredObject = hit.collider.gameObject),RayCast的做用差很少就是找到被擊中的對象,賦給hoveredObject,回過頭來,由於hoveredObject對象保存的是被擊中的對象,在ProcessMouse方法裏for (int i = 0; i < 3; ++i) mMouse[i].current = hoveredObject;把此對象付給了mMouse[i],for循環之因此爲3次,由於鼠標有三個鍵,左鍵,滾輪鍵,右鍵,代碼繼續執行 code
// Process all 3 mouse buttons as individual touches
for (int i = 0; i < 3; ++i) {
bool pressed = Input.GetMouseButtonDown(i);
bool unpressed = Input.GetMouseButtonUp(i);
if (pressed || unpressed) currentScheme = ControlScheme.Mouse; currentTouch = mMouse[i]; currentTouchID = -1 - i; currentKey = KeyCode.Mouse0 + i;
if (pressed || unpressed)
// We don't want to update the last camera while there is a touch happening
if (pressed) currentTouch.pressedCam = currentCamera;
else if (currentTouch.pressed != null) currentCamera = currentTouch.pressedCam;
// Process the mouse events
ProcessTouch(pressed, unpressed); currentKey = KeyCode.None;
}
這裏能夠看到,射線擊中的對象被賦給了currentTouch對象了,當鼠標按下時,pressed表示是否按下,unpressed表示鼠標是否擡起,當咱們點擊按鈕知道完成,pressed和unpressed值會經歷這樣的變化:True,false -> false true,程序執行到ProcessTouch方法,由於咱們是點擊事件,因此此方法內部的Notify(currentTouch.pressed, "OnClick", null)這段代碼會被執行,繼續執行Notify方法: orm
static public void Notify(GameObject go, string funcName, object obj) {
if (mNotifying) return; mNotifying = true;
if (NGUITools.GetActive(go)) { go.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver);
if (genericEventHandler != null && genericEventHandler != go) { genericEventHandler.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver); } } mNotifying = false; }
內部是調用對象的SendMessage方法的,對SendMessage方法不懂得,能夠參照這篇文章: htm
http://www.cnblogs.com/MrZivChu/p/sendmessage.html 對象
就此就完成了整個onclick方法的執行了,由於Update方法是一直執行的,因此UICamera腳本會一直髮出射線來檢測鼠標或者觸屏事件,從而執行相應的方法,原理大概就是這樣!