NGUI UICamera理解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaixh_89/article/details/82496394

   关于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下的所有对象

组件参数如下:

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脚本实现的,虽然名字和事件无关,但这个脚本是处理事件的,这个官方网站有吐槽:

uicamera_poorly_name

然后我们来看UICamera脚本都有哪些设置参数:

uicamera_parameter

在介绍参数之前,先普及一下UICamera的原理。

UICamera就是通过在触摸/鼠标移动的位置的地方发射射线(就是Unity的Raycast),然后获取射线撞击的碰撞体(collider)信息,然后发射消息(通过Unity的SendMessage函数)给该碰撞体关联的GameObject的所有脚本

调用Raycast获取RaycastHit,从RaycastHit中获取collider,然后从collider获取碰触到的GameObject,最后通过SendMessage,向这个GameObject发送消息,至此脚本中的事件处理函数就执行到了

猜你喜欢

转载自blog.csdn.net/zhaixh_89/article/details/82496394