天天看點

NGUI UICamera了解Camera)事件處理

   關于UICamera的講解,網上内容真是一搜一大堆,一兩篇部落格轉來轉去,看着頭疼,自己看了下UICamera的源碼,結合各種部落格的講解,記錄下自己對這個重要腳本的了解,首先說下該腳本的作用。

UICamera是負責處理所有關于NGUI事件的,具體包括如圖(目前版本是3.12.1,各版本略有不同)

/// <summary>
/// This script should be attached to each camera that's used to draw the objects with
/// UI components on them. This may mean only one camera (main camera or your UI camera),
/// or multiple cameras if you happen to have multiple viewports. Failing to attach this
/// script simply means that objects drawn by this camera won't receive UI notifications:
/// 
/// * OnHover (isOver) is sent when the mouse hovers over a collider or moves away.
/// * OnPress (isDown) is sent when a mouse button gets pressed on the collider.
/// * OnSelect (selected) is sent when a mouse button is first pressed on an object. Repeated presses won't result in an OnSelect(true).
/// * OnClick () is sent when a mouse is pressed and released on the same object.
///   UICamera.currentTouchID tells you which button was clicked.
/// * OnDoubleClick () is sent when the click happens twice within a fourth of a second.
///   UICamera.currentTouchID tells you which button was clicked.
/// 
/// * OnDragStart () is sent to a game object under the touch just before the OnDrag() notifications begin.
/// * OnDrag (delta) is sent to an object that's being dragged.
/// * OnDragOver (draggedObject) is sent to a game object when another object is dragged over its area.
/// * OnDragOut (draggedObject) is sent to a game object when another object is dragged out of its area.
/// * OnDragEnd () is sent to a dragged object when the drag event finishes.
/// 
/// * OnTooltip (show) is sent when the mouse hovers over a collider for some time without moving.
/// * OnScroll (float delta) is sent out when the mouse scroll wheel is moved.
/// * OnNavigate (KeyCode key) is sent when horizontal or vertical navigation axes are moved.
/// * OnPan (Vector2 delta) is sent when when horizontal or vertical panning axes are moved.
/// * OnKey (KeyCode key) is sent when keyboard or controller input is used.
/// </summary>
           
  • OnHover (isOver) 發送時機為滑鼠懸停(隻觸發一次)或者離開。
  • OnPress (isDown) 發送時機為滑鼠按下。
  • OnSelect (selected)發送時機為滑鼠點選和松開的時候都在同一個object上。
  • OnClick ()發送時機和OnSelect一樣,但是要求滑鼠沒有移動特别多。UICamera.currentTouchID表示按下的滑鼠哪個鍵。
  • OnDoubleClick ()發送時機為當在四分之一秒内click兩次的時候。UICamera.currentTouchID表示按下的滑鼠哪個鍵。
  • OnDragStart ()發送時機為OnDrag()事件之前。
  • OnDrag (delta) 發送時機為一個object被拖拽。
  • OnDragOver (draggedObject)發送時機為其他的object拖拽到他的上面。
  • OnDragOut (draggedObject)發送時機為其他的object拖拽出他的上面。
  • OnDragEnd ()發送時機為drag事件結束。發送給被拖拽的object。
  • OnInput (text)發送時機為輸入的時候(在點選選擇了一個collider之後)。
  • OnTooltip (show) 發送時機為滑鼠懸停在一個collider上一段時間沒有移動。
  • OnScroll (float delta)發送時機為滑鼠滾輪滾動。
  • OnKey (KeyCode key)發送時機為鍵盤或者輸入控制器被使用的時候。
  • OnNavigate (KeyCode key)當水準或者垂直導航軸移動時觸發
  • OnPan(Vector2 delta)當水準或者垂直平行軸移動時觸發

隻有将其附加在場景中的Camera上,才能将NGUI事件發送給Camera下的所有對象

元件參數如下:

NGUI UICamera了解Camera)事件處理

EventType:

[DoNotObfuscateNGUI] public enum EventType : int
	{
		World_3D,	// Perform a Physics.Raycast and sort by distance to the point that was hit.
		UI_3D,		// Perform a Physics.Raycast and sort by widget depth.
		World_2D,	// Perform a Physics2D.OverlapPoint
		UI_2D,		// Physics2D.OverlapPoint then sort by widget depth
	}
           

事件類型包括UI,World,用于區分UICamera處理UI事件的對象是UI控件還是3D物體。如果是UI模式,事件順序基于widget的depth——和渲染順序一樣,如果是3D模式則根據與相機的距離來排序點選到的object,為了結構清晰,是以,一般情況下,遊戲場景中需要一個UICamera負責UI對象,另外一個UICamera負責非UI對象。

Events to go:

/// <summary>
/// By default, events will go to rigidbodies when the Event Type is not UI.
/// You can change this behaviour back to how it was pre-3.7.0 using this flag.
/// </summary>
public bool eventsGoToColliders = false;
           

用于确定接受事件的是Collider還是RigidBody。對于NGUI的控件,這兩者處理是沒有差別的,主要差別還是在處理使用者自定義的GameObject上 ,隻有當我們在Event Type中選擇了World開頭的選項這個Events to go才起作用哦,否則NGUI都會預設為Collider。針對這個選項有位朋友解釋得不錯,“我們之前說過“要是想要觸摸使用者在遊戲場景中建立的物體,那麼請選擇World開頭的選項”,而如果我們要“觸摸”遊戲場景中的物體,在有些情況下,觸摸“Collider”是沒有辦法滿足條件的,必須觸摸“剛體”才行。比如我們制作了一艘船,我們這個船是一個完整的剛體,但是船頭,船身和船尾為三個子物體并分别有三個Collider,這是為了實作“當炮彈命中不同的位置,受傷情況不同”這一效果。但是這就給觸摸船隻造成麻煩,因為不管觸摸哪個部位,都無法讓整個船都接受到事件。這個時候我們如果在這個選擇了RigidBody,那麼處理事件的載體就變為了三個部分的根節點的那個剛體得到事件,我們就可以調用所有的事件處理函數了”

Event Mask:該屬性用來決定哪些層會接收事件。大多數情況下你需要的就是“Everything”,這個值會與UnityEngine.Camera's Culling Mask進行邏輯與運算,有需要的話你可以微調這個值。如果你修改了UI的game object的Layer,記得調整Event Mask,否則你可能會發現UI不響應事件。

Debug:該屬性能用于調試目前滑鼠點選的是那個對象。如果當你點選一些按鈕的時候,你不知道目前和滑鼠事件互動的是什麼對象,隻要打開這個選項,你就能在頂部看到它。

ProcessEventsIn:

[DoNotObfuscateNGUI] public enum ProcessEventsIn
{
    Update,
    LateUpdate,
}

/// <summary>
/// When events will be processed.
/// </summary>
public ProcessEventsIn processEventsIn = ProcessEventsIn.Update;
           

該屬性用來設定事件什麼時候被處理

Command Click:在Mac電腦觸控闆上用command按鍵模拟右鍵操作

AllowMultiTouch:是否允許多點觸摸

AutoHideCursor:當遊戲控制器或者輸入裝置被檢測到時NGUI是否自動隐藏光标

Sticky Tooltip:如果關掉,當滑鼠再次移動的時候就會立即關掉tooltip。如果打開,隻要滑鼠一直在這個game object上,tooltip就會移至顯示。

Tooltip Delay:用來控制當滑鼠停在某個object上時,經過多長時間OnTooltip消息會被發送到這個object上。以秒為機關

Long Press Tooltip:如果可用,當我們一直按在某個對象上持續Tooltip Delay後将會收到提示消息

Raycast Range:控制射線的長度,大多數情況下這個值可以被忽略(-1表示無限遠)。這個值是世界坐标系的值,是以如果你的錄影機的near clip是0.3、far clipping是 1000,比較遠的物體可能不會響應click事件,比如可以把這個值設定為2000(比far和near clipping大的值。)

Event Sources:用來确定哪些事件類型會被處理。被勾選掉的事件就不會被處理。有些平台會強制關閉一些事件。比如使用搖桿時會自動關掉滑鼠和touch時事件。

Thresholds:調整click、drag和tap(輕敲、拍打)事件的門檻值來微調滑鼠和touch事件的行為。以像素為機關。

Axes和Keys:部分用來控制哪個軸控制哪個方向的移動。這些名字需要和Input Manager裡面的一緻。

下面簡單理下UICamera的原理:其實就是射線碰撞檢測

Camera)事件處理

今天來談談有關NGUI的事件處理。

NGUI的事件處理是由UICamera腳本實作的,雖然名字和事件無關,但這個腳本是處理事件的,這個官方網站有吐槽:

NGUI UICamera了解Camera)事件處理

然後我們來看UICamera腳本都有哪些設定參數:

NGUI UICamera了解Camera)事件處理

在介紹參數之前,先普及一下UICamera的原理。

UICamera就是通過在觸摸/滑鼠移動的位置的地方發射射線(就是Unity的Raycast),然後擷取射線撞擊的碰撞體(collider)資訊,然後發射消息(通過Unity的SendMessage函數)給該碰撞體關聯的GameObject的所有腳本

調用Raycast擷取RaycastHit,從RaycastHit中擷取collider,然後從collider擷取碰觸到的GameObject,最後通過SendMessage,向這個GameObject發送消息,至此腳本中的事件處理函數就執行到了