当前位置: 首页 > news >正文

网站中 点击出现登录框怎么做/外贸网站推广

网站中 点击出现登录框怎么做,外贸网站推广,免费广告推广网站,电商客服主要做什么Unity中的UGUI源码解析之事件系统(5)-RayCaster(上) 今天要分享的是事件系统中的射线投射器(RayCaster). Unity使用射线投射器来收集和鉴别被点击的游戏对象. 射线投射的原理很简单, 就是在屏幕点击的位置发射一条射线, 根据一些规则收集被射线穿透的对象, 然后再根据一些规…

Unity中的UGUI源码解析之事件系统(5)-RayCaster(上)

今天要分享的是事件系统中的射线投射器(RayCaster).

Unity使用射线投射器来收集和鉴别被点击的游戏对象.

射线投射的原理很简单, 就是在屏幕点击的位置发射一条射线, 根据一些规则收集被射线穿透的对象, 然后再根据一些规则将这些对象排序, 选出距离屏幕最近的对象, 最后在这个对象上进行各种事件操作.

所以研究射线投射就是要围绕这个原理来展开, 有了方向, 我们才不会陷入各种代码中变得一头懵.

由于内容比较多, 我们分山下两篇文章来介绍.

相关的类

射线投射相关的类有下面几个:

  • Ray: 射线类
  • RaycastResult: 投射结果
  • RaycasterManager: 投射器管理器
  • BaseRaycaster: 射线投射基类
  • GraphicRaycaster : BaseRaycaster: 图形投射器
  • PhysicsRaycaster : BaseRaycaster: 针对3D物体的投射器, 需要对象上同时存在Camera组件
  • Physics2DRaycaster : PhysicsRaycaster: 针对2D物体的投射器, 需要对象上同时存在Camera组件

Ray

射线是从某一个点朝着某个方向发射的有限线段, Unity使用Camera的相关接口来发射射线.

Camera发射射线的原理很简单, 就是从Camera的近平面(不管是透视投影还是平行投影)的对应位置发送一条穿过指定点的射线.

发射点原则上是按照比例在视口上计算出来, 这个比例根据目标点在自己的坐标系中的比例来确定.

最后得出的射线使用世界坐标来描述.

  • public Ray ViewportPointToRay(Vector3 position): 从摄像机发送一条射线, 经过ViewRect(视口, 一般坐标是0到1之间)的指定点
  • public Ray ScreenPointToRay(Vector3 position): 从摄像机发送一条射线, 经过Screen坐标的指定点

Ray本身是一个结构体, 提供发射点坐标和发射方向的属性, 还提供了一个获取指定长度的射线终点的坐标接口, 注意这里说的坐标都是世界坐标.

public Vector3 origin
{get => this.m_Origin;set => this.m_Origin = value;
}// 这个方向是标准化过后的
public Vector3 direction
{get => this.m_Direction;set => this.m_Direction = value.normalized;
}public Vector3 GetPoint(float distance) => this.m_Origin + this.m_Direction * distance;

RaycastResult

投射结果, 本身是一个结构体, 封装投射相关的数据.

// 投射击中(射线穿过)的对象
private GameObject m_GameObject;// 相关的投射器
public BaseRaycaster module;// 击中距离(从射线起始点到击中点)
public float distance;// 排序索引
public float index;// 排序深度
public int depth;// 排序sortingLayer
public int sortingLayer;// 排序sortingOrder
public int sortingOrder;// 击中点的世界坐标
public Vector3 worldPosition;// 击中点的世界法线
public Vector3 worldNormal;// 击中点的屏幕坐标
public Vector2 screenPosition;// 是否有效
public bool isValid
{get { return module != null && gameObject != null; }
}

RaycasterManager

RaycasterManager是一个静态类, 通过静态列表维护所有的投射器, 在投射器的生命周期函数OnEnable/OnDisable时加入列表和从列表中移除.

internal static class RaycasterManager
{private static readonly List<BaseRaycaster> s_Raycasters = new List<BaseRaycaster>();public static void AddRaycaster(BaseRaycaster baseRaycaster){if (s_Raycasters.Contains(baseRaycaster))return;s_Raycasters.Add(baseRaycaster);}public static List<BaseRaycaster> GetRaycasters(){return s_Raycasters;}// 这个名字明显不需要带"s", 看来Unity的程序大佬也喜欢复制黏贴嘛, 哈哈public static void RemoveRaycasters(BaseRaycaster baseRaycaster){if (!s_Raycasters.Contains(baseRaycaster))return;s_Raycasters.Remove(baseRaycaster);}
}

代码不多, 也比较简单, 我就直接贴出来了.

BaseRaycaster

BaseRaycaster是一个抽象类, 继承于UIBehaviour, 提供一些基础行为, 最主要的就是定义投射接口, 摄像机属性加入和移除投射管理器的行为, 同时提供了一些基础属性供其它模块使用.

public abstract class BaseRaycaster : UIBehaviour
{// 核心的投射接口public abstract void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList);// 用于生成射线的摄像机public abstract Camera eventCamera { get; }protected override void OnEnable(){base.OnEnable();RaycasterManager.AddRaycaster(this);}protected override void OnDisable(){RaycasterManager.RemoveRaycaster(this);base.OnDisable();}// 这个也参与之前文章提到的信息展示public override string ToString(){return "Name: " + gameObject + "\n" +"eventCamera: " + eventCamera + "\n" +"sortOrderPriority: " + sortOrderPriority + "\n" +"renderOrderPriority: " + renderOrderPriority;}// 排序优先级, 用于射线排序比较, 在EventSystem组件中的比较函数中使用public virtual int sortOrderPriority{get { return int.MinValue; }}// 渲染顺序优先级, 用于射线排序比较, 在EventSystem组件中的比较函数中使用public virtual int renderOrderPriority{get { return int.MinValue; }}
}

EventSystem中用于投射的方法

在前面的文章中, 我们说过, EventSystem中提供了一些用于投射的方法, 不太清楚为什么放在这里, 个人感觉放在RaycasterManager更合适一点.

// 投射结果比较器, 用于排序RaycastResult
// 总体上是按照: 优先级越大, 深度越大, 越后渲染, 距离摄像机越近, 索引越小, 则越靠前
private static int RaycastComparer(RaycastResult lhs, RaycastResult rhs)
{// 优先比较投射器if (lhs.module != rhs.module){var lhsEventCamera = lhs.module.eventCamera;var rhsEventCamera = rhs.module.eventCamera;// 两者摄像机都存在且深度不同时, 使用摄像机的深度排序if (lhsEventCamera != null && rhsEventCamera != null && lhsEventCamera.depth != rhsEventCamera.depth){// need to reverse the standard compareToif (lhsEventCamera.depth < rhsEventCamera.depth)return 1;if (lhsEventCamera.depth == rhsEventCamera.depth)return 0;return -1;}// sortOrderPriority排序if (lhs.module.sortOrderPriority != rhs.module.sortOrderPriority)return rhs.module.sortOrderPriority.CompareTo(lhs.module.sortOrderPriority);// renderOrderPriority排序if (lhs.module.renderOrderPriority != rhs.module.renderOrderPriority)return rhs.module.renderOrderPriority.CompareTo(lhs.module.renderOrderPriority);}// sortingLayer排序if (lhs.sortingLayer != rhs.sortingLayer){// Uses the layer value to properly compare the relative order of the layers.var rid = SortingLayer.GetLayerValueFromID(rhs.sortingLayer);var lid = SortingLayer.GetLayerValueFromID(lhs.sortingLayer);return rid.CompareTo(lid);}// sortingOrder排序if (lhs.sortingOrder != rhs.sortingOrder)return rhs.sortingOrder.CompareTo(lhs.sortingOrder);// depth排序if (lhs.depth != rhs.depth)return rhs.depth.CompareTo(lhs.depth);// distance排序[从小到大]if (lhs.distance != rhs.distance)return lhs.distance.CompareTo(rhs.distance);// index排序[从小到大]return lhs.index.CompareTo(rhs.index);
}private static readonly Comparison<RaycastResult> s_RaycastComparer = RaycastComparer;// 使用事件数据对所有投射器进行投射, 获取排序后的投射结果, 主要使用位置属性
public void RaycastAll(PointerEventData eventData, List<RaycastResult> raycastResults)
{raycastResults.Clear();var modules = RaycasterManager.GetRaycasters();for (int i = 0; i < modules.Count; ++i){var module = modules[i];if (module == null || !module.IsActive())continue;module.Raycast(eventData, raycastResults);}raycastResults.Sort(s_RaycastComparer);
}

总结

今天介绍了射线投射器的基础部分, 下一篇文章会介绍几个具体的投射器, 希望对大家所有帮助.

http://www.jmfq.cn/news/5096827.html

相关文章:

  • 百度网站的优化方案/百度app官网
  • 临沂外贸网站/太原seo哪家好
  • 儋州网站建设培训学校/哪家建设公司网站
  • 免费做网站txt外链/关键词检索怎么弄
  • 网站开发实习/网站秒收录
  • 介绍自己做的电影网站/新站网站推广公司
  • 网站建设开发费用/seo1短视频网页入口营销
  • 政府网站建设改进措施/宁德市安全教育平台
  • 那个网站的是做vb题目的/站内搜索引擎
  • 郑州网站建设直播/软文写作公司
  • 唐山网站建设公司/seo营销外包
  • 专业做高品质的代工网站/简述网络营销的特点及功能
  • 做钢材的网站/广州seo网站排名
  • 定兴做网站/seo的课谁讲的好
  • 实验建设网站 南京林业大学/含有友情链接的网页
  • 英文网站建设电话咨询/cpa游戏推广联盟
  • 深圳大型论坛网站建设/武汉网站推广
  • wordpress 新闻采集站/泰安seo培训
  • 苏州行业网站建设服务/aso苹果关键词优化
  • wordpress转移服务器/seo代理计费系统
  • 山东网站建设公司哪家好/推广网站有哪些
  • 天津做网站哪家公司好/seo网站优化排名
  • 成都网站建设潮州/网站建设公司简介
  • 网站必须要求备案吗/爱站网关键词密度
  • 网站是由哪些组成/seo推广网站
  • dw软件下载官方网站/邯郸seo排名
  • 想做网站的公司/seo公司 上海
  • 响应式网站制作公司/千锋教育培训机构怎么样
  • 网站域名备案办理拍照/百度手机卫士
  • 上传图片分享链接/青岛百度推广优化怎么做的