想知道生命的意义吗中三的方案有哪些啊?

您现在的位置: >
小米3死机怎么办?小米3死机如何重启的方法
  小米3死机了怎么办?小米3死机如何重启?我们都知道小米手机3的后盖无法打开,死机了也不能拆后盖拔电池来重启手机。这里小编就来分享一下小米3死机重启方法,如果你不知道小米3死机如何重启的话,可以来参考一下本教程。
  小米3死机怎么办?其实方法很简单,我们不需要太纠结于小米手机3不可拆卸后盖电池的设计,现在锂离子电池的使用寿命在3年左右,这款手机的机身内部也是独立电池。
  而且,目前采用一体式机身设计的智能手机也大都会考虑使用卡机、死机的问题,我们可以通过使用物理按键组合的方式让手机重启。小米3重启的技巧就是长按电源键+音量上键,就可让手机重启了。
相关文章:小米3 小米3死机 小米3死机如何重启
图解新闻:
最新攻略:
24小时更新:
热门排行本周本月
推荐文章本周本月不知道怎么开发VR游戏?Unity5.3官方VR教程重磅登场-系列3 VR中的交互方式2 years ago赞赏还没有人赞赏,快来当第一个赞赏的人吧!32收藏分享举报文章被以下专栏收录Learning by Playing,游戏改变…推荐阅读{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[{&sourceColumn&:{&lastUpdated&:,&description&:&Learning by Playing,游戏改变学习,让k12青少年爱上编程。&,&permission&:&COLUMN_PUBLIC&,&memberId&:10925,&contributePermission&:&COLUMN_PUBLIC&,&translatedCommentPermission&:&all&,&canManage&:true,&intro&:&Learning by Playing,游戏改变…&,&urlToken&:&kidscoding&,&id&:602,&imagePath&:&f9a1d3e049.jpeg&,&slug&:&kidscoding&,&applyReason&:&&,&name&:&笨猫快乐学编程&,&title&:&笨猫快乐学编程&,&url&:&https:\u002F\\u002Fkidscoding&,&commentPermission&:&COLUMN_ALL_CAN_COMMENT&,&canPost&:true,&created&:,&state&:&COLUMN_NORMAL&,&followers&:7709,&avatar&:{&id&:&f9a1d3e049&,&template&:&https:\u002F\\u002F{id}_{size}.jpeg&},&activateAuthorRequested&:false,&following&:false,&imageUrl&:&https:\u002F\\u002Ff9a1d3e049_l.jpeg&,&articlesCount&:88},&state&:&accepted&,&targetPost&:{&titleImage&:&https:\u002F\\u002F7ad35cf7b1ad7a9a8ba410_r.jpg&,&lastUpdated&:,&imagePath&:&7ad35cf7b1ad7a9a8ba410.jpg&,&permission&:&ARTICLE_PUBLIC&,&topics&:[],&summary&:&\u003Cb\u003E概览:\u003C\u002Fb\u003E在VR项目中,我们需要在用户”凝视“某个物体时将其激活。在VRSamples中,我们构建了一个简单的,可拓展的轻度系统,让用户跟场景中的物体进行交互。其中包含了三个主要的脚本文件:VREyeRaycaster,VRInput和VRInteractiveItem,下面将对这三个重要的…&,&copyPermission&:&ARTICLE_COPYABLE&,&translatedCommentPermission&:&all&,&likes&:0,&origAuthorId&:10925,&publishedTime&:&T11:13:48+08:00&,&sourceUrl&:&&,&urlToken&:,&id&:384905,&withContent&:false,&slug&:,&bigTitleImage&:false,&title&:&不知道怎么开发VR游戏?Unity5.3官方VR教程重磅登场-系列3 VR中的交互方式&,&url&:&\u002Fp\u002F&,&commentPermission&:&ARTICLE_ALL_CAN_COMMENT&,&snapshotUrl&:&&,&created&:,&comments&:0,&columnId&:602,&content&:&&,&parentId&:0,&state&:&ARTICLE_PUBLISHED&,&imageUrl&:&https:\u002F\\u002F7ad35cf7b1ad7a9a8ba410_r.jpg&,&author&:{&bio&:&Apple,SF,Psychology&,&isFollowing&:false,&hash&:&4c9dd7ce259e3e6ae2f0fa6ca42801ee&,&uid&:00,&isOrg&:false,&slug&:&eseedo&,&isFollowed&:false,&description&:&Create a world like Caprica.&,&name&:&王寒&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Feseedo&,&avatar&:{&id&:&7dd67dbfe&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false},&memberId&:10925,&excerptTitle&:&&,&voteType&:&ARTICLE_VOTE_CLEAR&},&id&:319927}],&title&:&不知道怎么开发VR游戏?Unity5.3官方VR教程重磅登场-系列3 VR中的交互方式&,&author&:&eseedo&,&content&:&\u003Cp\u003E\u003Cb\u003E概览:\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E在VR项目中,我们需要在用户”凝视“某个物体时将其激活。在VRSamples中,我们构建了一个简单的,可拓展的轻度系统,让用户跟场景中的物体进行交互。其中包含了三个主要的脚本文件:VREyeRaycaster,VRInput和VRInteractiveItem,下面将对这三个重要的类进行简要的介绍。相关的源代码也做了注释。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003EVREyeRaycaster\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F6a51cf1edcc7d_b.png\& data-rawwidth=\&599\& data-rawheight=\&178\& class=\&origin_image zh-lightbox-thumb\& width=\&599\& data-original=\&https:\u002F\\u002F6a51cf1edcc7d_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='599'%20height='178'&&\u002Fsvg&\& data-rawwidth=\&599\& data-rawheight=\&178\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&599\& data-original=\&https:\u002F\\u002F6a51cf1edcc7d_r.png\& data-actualsrc=\&https:\u002F\\u002F6a51cf1edcc7d_b.png\&\u003E\u003Cp\u003E该脚本需要和Main Camera关联。在每次调用Update()时,该脚本都会使用Physics.Raycast来投射一条射线,以确认该射线是否命中任何collider(碰撞体)。使用该脚本还可以排除特定的\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002FManual\u002FLayers.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EUnity - Manual: Layers\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E-在某些场景中,我们可能为了性能考虑,把所有的可交互对象移到一个单独的层。\u003C\u002Fp\u003E\u003Cp\u003E如果某个碰撞体被射线命中,那么该脚本将尝试在GameObject上找到一个VRInteractiveItem组件。\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003EVRInteractiveItem interactible = hit.collider.GetComponent&VRInteractiveItem&();
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002Fattempt to get the VRInteractiveItem on the hit object\u003C\u002Fp\u003E\u003Cp\u003E从这里我们就可以判断用户究竟在”凝视“哪个物体,或是停止”凝视“某个物体。如果用户开始或停止”凝视“某个物体,那么我们就可以进行一些处理,比如调用一个方法。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003EVRInput\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F29cdf77acba5fad440a7ed83_b.png\& data-rawwidth=\&568\& data-rawheight=\&73\& class=\&origin_image zh-lightbox-thumb\& width=\&568\& data-original=\&https:\u002F\\u002F29cdf77acba5fad440a7ed83_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='568'%20height='73'&&\u002Fsvg&\& data-rawwidth=\&568\& data-rawheight=\&73\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&568\& data-original=\&https:\u002F\\u002F29cdf77acba5fad440a7ed83_r.png\& data-actualsrc=\&https:\u002F\\u002F29cdf77acba5fad440a7ed83_b.png\&\u003E\u003Cp\u003EVRInput是个简单的类,可以判断用户在GearVR上(或是使用DK2时在PC上)所进行的一些简单操作,比如滑动、触碰、或双触。\u003C\u002Fp\u003E\u003Cp\u003E我们可以直接在VRInput上订阅事件:\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action&SwipeDirection& OnS
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Called every frame passing in the swipe, including if there is no swipe.\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action OnC
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Called when Fire1 is released and it's not a double click.\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action OnD
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Called when Fire1 is pressed.\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action OnUp;
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Called when Fire1 is released.\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action OnDoubleC
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Called when a double click is detected.\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action OnC
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Called when Cancel is pressed.\u003C\u002Fp\u003E\u003Cp\u003E关于订阅事件的更多信息,请参考这里。\u003Ca href=\&http:\u002F\\u002F?target=http%3A\\u002Flearn\u002Ftutorials\u002Fmodules\u002Fintermediate\u002Fscripting\u002Fevents\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EUnity - Events\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003EVRInteractiveItem\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E我们可以把该组件添加到任何希望在VR场景中进行交互的GameObject上,在该物体上需要绑定一个碰撞体。\u003C\u002Fp\u003E\u003Cp\u003E对此我们可以选择订阅六种不同的事件:\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action OnO
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Called when the gaze moves over this object\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action OnO
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Called when the gaze leaves this object\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action OnC
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Called when click input is detected whilst the gaze is over this object.\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action OnDoubleC
\u003C\u002Fp\u003E\u003Cp\u003E \u002F\u002F Called when double click input is detected whilst the gaze is over this object.\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action OnUp;
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Called when Fire1 is released whilst the gaze is over this object.\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action OnD
\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Called when Fire1 is pressed whilst the gaze is over this object.\u003C\u002Fp\u003E\u003Cp\u003E此外还有一个布尔值用于判断用户是否”凝视“在当前物体上?\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Epublic bool IsOver\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
get{ return m_IsO }
\u002F\u002F Is the gaze currently over this object?\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003E我们也可以创建自己的脚本对以上事件作出响应。下面是一个简单的示例:\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Eusing UnityE\u003C\u002Fp\u003E\u003Cp\u003Eusing VRStandardAssets.U\u003C\u002Fp\u003E\u003Cp\u003Enamespace VRStandardAssets.Examples\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F This script is a simple example of how an interactive item can\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F be used to change things on gameobjects by handling events.\u003C\u002Fp\u003E\u003Cp\u003E
public class ExampleInteractiveItem : MonoBehaviour\u003C\u002Fp\u003E\u003Cp\u003E
{\u003C\u002Fp\u003E\u003Cp\u003E
[SerializeField] private Material m_NormalM
\u003C\u002Fp\u003E\u003Cp\u003E
[SerializeField] private Material m_OverM
\u003C\u002Fp\u003E\u003Cp\u003E
[SerializeField] private Material m_ClickedM
\u003C\u002Fp\u003E\u003Cp\u003E
[SerializeField] private Material m_DoubleClickedM
\u003C\u002Fp\u003E\u003Cp\u003E
[SerializeField] private VRInteractiveItem m_InteractiveI\u003C\u002Fp\u003E\u003Cp\u003E
[SerializeField] private Renderer m_R\u003C\u002Fp\u003E\u003Cp\u003E
private void Awake ()\u003C\u002Fp\u003E\u003Cp\u003E
{\u003C\u002Fp\u003E\u003Cp\u003E
m_Renderer.material = m_NormalM\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E如果想看到实际的示例,不妨看看VRSampleScens\u002FScens\u002FExamples\u002F的InteractiveItem场景。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003ESelectionRadial和SelectionSlider\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E我们同时利用了radial选择条(SelectionRadial),以及选择滑动条(SelectionSlider),这样用户就可以按住Fire1来确认某个交互:\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fee0898faef581de805fd0_b.png\& data-rawwidth=\&524\& data-rawheight=\&457\& class=\&origin_image zh-lightbox-thumb\& width=\&524\& data-original=\&https:\u002F\\u002Fee0898faef581de805fd0_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='524'%20height='457'&&\u002Fsvg&\& data-rawwidth=\&524\& data-rawheight=\&457\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&524\& data-original=\&https:\u002F\\u002Fee0898faef581de805fd0_r.png\& data-actualsrc=\&https:\u002F\\u002Fee0898faef581de805fd0_b.png\&\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fc64fdee877_b.png\& data-rawwidth=\&622\& data-rawheight=\&290\& class=\&origin_image zh-lightbox-thumb\& width=\&622\& data-original=\&https:\u002F\\u002Fc64fdee877_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='622'%20height='290'&&\u002Fsvg&\& data-rawwidth=\&622\& data-rawheight=\&290\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&622\& data-original=\&https:\u002F\\u002Fc64fdee877_r.png\& data-actualsrc=\&https:\u002F\\u002Fc64fdee877_b.png\&\u003E\u003Cp\u003E当按住输入键时,选择条会进行填充,并在填充完整后分发OnSelectionComplete或OnBarFilled事件。关于此部分的代码,可以在SelectionRadial.cs和SelectionSlider.cs中找到,并进行了详细的注释。\u003C\u002Fp\u003E\u003Cp\u003E在VR的世界里,从用户交互的角度看,用户需要时刻知道自己在做什么,而且可以掌控一切。通过这种“held input”的确认输入方式,可以确保用户不会出现误操作。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003EVR Sample项目中的交互示例\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E现在让我们来一起看看VR Sample项目中的部分交互示例。我们将提到每个场景中所使用的交互方式,以及具体实现的方式。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003EMenu 场景中的交互\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E每个menu场景都包含了几个组件,其中我们需要重点关注的是MenuButton,VRInteractiveItem和Mesh Collider。\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F0f4c53d5e819ceb89969d3_b.png\& data-rawwidth=\&624\& data-rawheight=\&240\& class=\&origin_image zh-lightbox-thumb\& width=\&624\& data-original=\&https:\u002F\\u002F0f4c53d5e819ceb89969d3_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='624'%20height='240'&&\u002Fsvg&\& data-rawwidth=\&624\& data-rawheight=\&240\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&624\& data-original=\&https:\u002F\\u002F0f4c53d5e819ceb89969d3_r.png\& data-actualsrc=\&https:\u002F\\u002F0f4c53d5e819ceb89969d3_b.png\&\u003E\u003Cp\u003EMenuButton组件订阅了VRInteractiveItem组件上的OnOver和OnOut事件,这样当十字准星移到menu上时,selection radial会出现。当用户的实现离开菜单选项时,selection radial会消失。而当selection radial可见,且用户按住Fire1键时,则radial会自动填充:\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fee0898faef581de805fd0_b.png\& data-rawwidth=\&524\& data-rawheight=\&457\& class=\&origin_image zh-lightbox-thumb\& width=\&524\& data-original=\&https:\u002F\\u002Fee0898faef581de805fd0_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='524'%20height='457'&&\u002Fsvg&\& data-rawwidth=\&524\& data-rawheight=\&457\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&524\& data-original=\&https:\u002F\\u002Fee0898faef581de805fd0_r.png\& data-actualsrc=\&https:\u002F\\u002Fee0898faef581de805fd0_b.png\&\u003E\u003Cp\u003E该类还订阅了OnSelectionRadial的OnSelectionComplete事件,这样当radial被填充满的时候,会调用HandleSelectionComplete。该方法的作用是让摄像机淡出,并调用所选的关卡。\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Eprivate void OnEnable ()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
m_InteractiveItem.OnOver += HandleO\u003C\u002Fp\u003E\u003Cp\u003E
m_InteractiveItem.OnOut += HandleO\u003C\u002Fp\u003E\u003Cp\u003E
m_SelectionRadial.OnSelectionComplete += HandleSelectionC\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003Eprivate void OnDisable ()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
m_InteractiveItem.OnOver -= HandleO\u003C\u002Fp\u003E\u003Cp\u003E
m_InteractiveItem.OnOut -= HandleO\u003C\u002Fp\u003E\u003Cp\u003E
m_SelectionRadial.OnSelectionComplete -= HandleSelectionC\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003Eprivate void HandleOver()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F When the user looks at the rendering of the scene, show the radial.\u003C\u002Fp\u003E\u003Cp\u003E
m_SelectionRadial.Show();\u003C\u002Fp\u003E\u003Cp\u003E
m_GazeOver =\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003Eprivate void HandleOut()\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F When the user looks away from the rendering of the scene, hide the radial.\u003C\u002Fp\u003E\u003Cp\u003E
m_SelectionRadial.Hide();\u003C\u002Fp\u003E\u003Cp\u003E
m_GazeOver =\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003Eprivate void HandleSelectionComplete()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F If the user is looking at the rendering of the scene when the radial's selection finishes, activate the button.\u003C\u002Fp\u003E\u003Cp\u003E
if(m_GazeOver)\u003C\u002Fp\u003E\u003Cp\u003E
StartCoroutine (ActivateButton());\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003Eprivate IEnumerator ActivateButton()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F If the camera is already fading, ignore.\u003C\u002Fp\u003E\u003Cp\u003E
if (m_CameraFade.IsFading)\u003C\u002Fp\u003E\u003Cp\u003E\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F If anything is subscribed to the OnButtonSelected event, call it.\u003C\u002Fp\u003E\u003Cp\u003E
if (OnButtonSelected != null)\u003C\u002Fp\u003E\u003Cp\u003E
OnButtonSelected(this);\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F Wait for the camera to fade out.\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
yield return StartCoroutine(m_CameraFade.BeginFadeOut(true));\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F Load the level.\u003C\u002Fp\u003E\u003Cp\u003E
SceneManager.LoadScene(m_SceneToLoad, LoadSceneMode.Single);\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003E让我们来看看Selection Radial的部分示例,注意截图中间的粉色元素:\u003C\u002Fp\u003E\u003Cp\u003EReticle only\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Feba7e48bc2c9279cce2dc4_b.png\& data-rawwidth=\&700\& data-rawheight=\&359\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002Feba7e48bc2c9279cce2dc4_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='359'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&359\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002Feba7e48bc2c9279cce2dc4_r.png\& data-actualsrc=\&https:\u002F\\u002Feba7e48bc2c9279cce2dc4_b.png\&\u003E\u003Cp\u003E当用户“凝视”菜单选项时,空白的Selection Radial可见。\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fde47bcc248abd0b9_b.png\& data-rawwidth=\&700\& data-rawheight=\&389\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002Fde47bcc248abd0b9_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='389'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&389\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002Fde47bcc248abd0b9_r.png\& data-actualsrc=\&https:\u002F\\u002Fde47bcc248abd0b9_b.png\&\u003E\u003Cp\u003ESelection Radial 填充(当用户“凝视”菜单选项,且按下fire1输入键)\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F0f7d3cb33c1_b.png\& data-rawwidth=\&700\& data-rawheight=\&370\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002F0f7d3cb33c1_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='370'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&370\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002F0f7d3cb33c1_r.png\& data-actualsrc=\&https:\u002F\\u002F0f7d3cb33c1_b.png\&\u003E\u003Cp\u003E在整个示例项目中,我们尝试用同样的风格,也就是使用bar和radial以固定的速度进行填充。在此建议大家在开发自己的VR项目时注意到这一点,因为交互设计中的连贯性对用户很重要,特别是对于VR这种新媒介。\u003C\u002Fp\u003E\u003Cp\u003EMaze场景中的交互\u003C\u002Fp\u003E\u003Cp\u003EMaze(迷宫)游戏中提供了一个桌面式的交互示例,其中我们可以指引游戏角色到出口,并避免触发炮塔。\u003C\u002Fp\u003E\u003Cp\u003E在选择角色的目的地时,会出现一个目的地标记,同时还会显示一个角色的路径。玩家可以通过在触摸板上使用swipe,按下方向键,或是使用游戏操纵杆上的左键来旋转视图。\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fc4292e9bea6_b.png\& data-rawwidth=\&700\& data-rawheight=\&421\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002Fc4292e9bea6_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='421'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&421\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002Fc4292e9bea6_r.png\& data-actualsrc=\&https:\u002F\\u002Fc4292e9bea6_b.png\&\u003E\u003Cp\u003E在MazeFloor游戏对象上关联了MeshCollider和VRInteractiveItem,从而允许在VR场景中进行交互:\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F5c32c09e102f84c7e117c_b.png\& data-rawwidth=\&487\& data-rawheight=\&301\& class=\&origin_image zh-lightbox-thumb\& width=\&487\& data-original=\&https:\u002F\\u002F5c32c09e102f84c7e117c_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='487'%20height='301'&&\u002Fsvg&\& data-rawwidth=\&487\& data-rawheight=\&301\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&487\& data-original=\&https:\u002F\\u002F5c32c09e102f84c7e117c_r.png\& data-actualsrc=\&https:\u002F\\u002F5c32c09e102f84c7e117c_b.png\&\u003E\u003Cp\u003EMazeCourse 游戏对象是一个parent对象,其中包含了MazeFloor和MazeWalls GameObjects,这两个对象依次包含了迷宫布局中的几何信息。\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F0f5fe48d2d40a5d719b8_b.png\& data-rawwidth=\&257\& data-rawheight=\&120\& class=\&content_image\& width=\&257\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='257'%20height='120'&&\u002Fsvg&\& data-rawwidth=\&257\& data-rawheight=\&120\& class=\&content_image lazy\& width=\&257\& data-actualsrc=\&https:\u002F\\u002F0f5fe48d2d40a5d719b8_b.png\&\u003E\u003Cp\u003EMazeCourse关联了一个MazeTargetSetting脚本,其中包含了对MazeFloor对象上VRInteractiveItem组件的引用。\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fe9f9e721bbc665ebec2594_b.png\& data-rawwidth=\&487\& data-rawheight=\&73\& class=\&origin_image zh-lightbox-thumb\& width=\&487\& data-original=\&https:\u002F\\u002Fe9f9e721bbc665ebec2594_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='487'%20height='73'&&\u002Fsvg&\& data-rawwidth=\&487\& data-rawheight=\&73\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&487\& data-original=\&https:\u002F\\u002Fe9f9e721bbc665ebec2594_r.png\& data-actualsrc=\&https:\u002F\\u002Fe9f9e721bbc665ebec2594_b.png\&\u003E\u003Cp\u003EMazeTargetSetting订阅了VRInteractiveItem上的OnDoubleClick事件,随后会分发OnTargetSet事件。该事件将把十字准星的Transform作为参数:\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Epublic event Action&Transform& OnTargetS
\u003C\u002Fp\u003E\u003Cp\u003E \u002F\u002F This is triggered when a destination is set.
\u003C\u002Fp\u003E\u003Cp\u003Eprivate void OnEnable()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
m_InteractiveItem.OnDoubleClick += HandleDoubleC\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003Eprivate void OnDisable()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
m_InteractiveItem.OnDoubleClick -= HandleDoubleC\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003Eprivate void HandleDoubleClick()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F If target setting is active and there are subscribers to OnTargetSet, call it.\u003C\u002Fp\u003E\u003Cp\u003E
if (m_Active && OnTargetSet != null)\u003C\u002Fp\u003E\u003Cp\u003E
OnTargetSet (m_Reticle.ReticleTransform);\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003EMazeCharacter游戏对象上的Player组件和MazeDestinationMarketGUI游戏对象上的DestinationMarker组件都会订阅该事件,并作出相应的响应。\u003C\u002Fp\u003E\u003Cp\u003E游戏角色可以使用Nav Mesh systems在迷宫中进行路径判断。Player组件使用HandleSetTarget函数来判断Nav Mesh Agent到十字准星间的方向,并更新Agent的轨迹-游戏角色路径的视觉渲染。\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Eprivate void HandleSetTarget(Transform target)\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F If the game isn't over set the destination of the AI controlling the character and the trail showing its path.\u003C\u002Fp\u003E\u003Cp\u003E
if (m_IsGameOver)\u003C\u002Fp\u003E\u003Cp\u003E
\u003C\u002Fp\u003E\u003Cp\u003E
m_AiCharacter.SetTarget(target.position);\u003C\u002Fp\u003E\u003Cp\u003E
m_AgentTrail.SetDestination();\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003EDestinationMarker可以将标记移动到Reticle的Transform位置:\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Eprivate void HandleTargetSet(Transform target)\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F When the target is set show the marker.\u003C\u002Fp\u003E\u003Cp\u003E
Show();\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F Set the marker's position to the target position.\u003C\u002Fp\u003E\u003Cp\u003E
transform.position = target.\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F Play the audio.\u003C\u002Fp\u003E\u003Cp\u003E
m_MarkerMoveAudio.Play();\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F Play the animation on whichever layer it is on, with no time offset.\u003C\u002Fp\u003E\u003Cp\u003E
m_Animator.Play(m_HashMazeNavMarkerAnimState, -1, 0.0f);\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003E在下图中可以看到reticle,目的地标记,玩家和轨迹。\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F470e01b7fcaf88d5ff1a3e_b.png\& data-rawwidth=\&700\& data-rawheight=\&350\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002F470e01b7fcaf88d5ff1a3e_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='350'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&350\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002F470e01b7fcaf88d5ff1a3e_r.png\& data-actualsrc=\&https:\u002F\\u002F470e01b7fcaf88d5ff1a3e_b.png\&\u003E\u003Cp\u003E迷宫中的切换开关也是在VR中和物体进行交互的示例,其中用到了Collider,以及VRInteractiveItem,和SelectionSlider三个类。\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F04fccbbbfe23efa_b.png\& data-rawwidth=\&487\& data-rawheight=\&444\& class=\&origin_image zh-lightbox-thumb\& width=\&487\& data-original=\&https:\u002F\\u002F04fccbbbfe23efa_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='487'%20height='444'&&\u002Fsvg&\& data-rawwidth=\&487\& data-rawheight=\&444\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&487\& data-original=\&https:\u002F\\u002F04fccbbbfe23efa_r.png\& data-actualsrc=\&https:\u002F\\u002F04fccbbbfe23efa_b.png\&\u003E\u003Cp\u003E正如上图中显示的,和其它交互对象一起,SelectionSlider脚本会监听由VRInteractiveItem和VRInput所分发的事件。\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Eprivate void OnEnable ()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
m_VRInput.OnDown += HandleD\u003C\u002Fp\u003E\u003Cp\u003E
m_VRInput.OnUp += HandleUp;\u003C\u002Fp\u003E\u003Cp\u003E
m_InteractiveItem.OnOver += HandleO\u003C\u002Fp\u003E\u003Cp\u003E
m_InteractiveItem.OnOut += HandleO\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003EFlyer场景中的交互\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003EFlyer场景是一个计时”无尽飞行”游戏,在其中玩家可以通过四处看来引导飞船的方向,并使用Fire1输入键进行射击,通过击中陨石或是引导飞船穿越空中的门来得分,跟Pilotwings或Starfox这两款游戏有点类似。\u003C\u002Fp\u003E\u003Cp\u003E在交互方面,Flyer使用了更简单的方式,也就是让FlyerLaserController订阅VRInput的OnDown事件,从而发射激光。\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Eprivate void OnEnable()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
m_VRInput.OnDown += HandleD\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003Eprivate void HandleDown()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F If the game isn't running return.\u003C\u002Fp\u003E\u003Cp\u003E
if (!m_GameController.IsGameRunning)\u003C\u002Fp\u003E\u003Cp\u003E\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F Fire laser from each position.\u003C\u002Fp\u003E\u003Cp\u003E
SpawnLaser(m_LaserSpawnPosLeft);\u003C\u002Fp\u003E\u003Cp\u003E
SpawnLaser(m_LaserSpawnPosRight);\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003EShooter180和Shooter360场景中的交互(Target Gallery\u002F Target Arena)。\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E在VR Samples包含了两个射击游戏,其中一个是回廊射击游戏,玩家在180度视角的走廊中对潜在目标射击。另外还有一个竞技场射击游戏,玩家被类似X战警场景的潜在目标包围。\u003C\u002Fp\u003E\u003Cp\u003E这两款游戏中的每个目标对象都有一个Collider,VRInteractiveItem和ShootingTarget。\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F2f0d90fd6bbfb6b264d6c_b.png\& data-rawwidth=\&529\& data-rawheight=\&456\& class=\&origin_image zh-lightbox-thumb\& width=\&529\& data-original=\&https:\u002F\\u002F2f0d90fd6bbfb6b264d6c_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='529'%20height='456'&&\u002Fsvg&\& data-rawwidth=\&529\& data-rawheight=\&456\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&529\& data-original=\&https:\u002F\\u002F2f0d90fd6bbfb6b264d6c_r.png\& data-actualsrc=\&https:\u002F\\u002F2f0d90fd6bbfb6b264d6c_b.png\&\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fca3c70a97b5cd352ee0bdeda365c0c24_b.png\& data-rawwidth=\&486\& data-rawheight=\&294\& class=\&origin_image zh-lightbox-thumb\& width=\&486\& data-original=\&https:\u002F\\u002Fca3c70a97b5cd352ee0bdeda365c0c24_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='486'%20height='294'&&\u002Fsvg&\& data-rawwidth=\&486\& data-rawheight=\&294\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&486\& data-original=\&https:\u002F\\u002Fca3c70a97b5cd352ee0bdeda365c0c24_r.png\& data-actualsrc=\&https:\u002F\\u002Fca3c70a97b5cd352ee0bdeda365c0c24_b.png\&\u003E\u003Cp\u003EShootingTarget组件订阅了VRInteractiveItem的OnDown事件,以判断目标是否被击中。该方法适用于瞬间命中(比如激光枪这种)的设定,如果要展示子弹时间,我们就需要考虑其它解决方案了。\u003C\u002Fp\u003E\u003Cp\u003E现在我们应该对基本的VR交互组件有了大概的印象,包括任何在VR Samples项目中具体使用这些组件。现在让我们来看看VR Samples项目中如何使用gaze(凝视)和reticles(十字星)。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003EGAZE(凝视)\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E在VR应用中判断用户正在看什么很重要,可能是用于判断用户和游戏对象的交互,或是触发一个动画,也可能是向目标发射子弹。我们将VR中“看”这个动作定义为gaze(凝视),而在后续的教程中我们将频繁使用这个词。\u003C\u002Fp\u003E\u003Cp\u003E考虑到目前大多数HMD头戴设备还不支持眼部追踪,因此我们只能估计用户的gaze(凝视)。透镜的扭曲意味着用户正看着正前方,有一个简单的解决方案。正如在概览中提到的,我们只需要从摄像机的中心发射一条射线,然后找到这条射线所碰撞的物体即可。当然,这就意味着所有要被碰撞(或是需要通过“凝视”进行交互)的对象都必须关联一个Collider组件。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003EReticle(十字准星)\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E十字准星用于辅助标记用户视野的中心。十字准星的样式可能是简单的点,也可能是一个十字准线,具体形式取决于项目需求。\u003C\u002Fp\u003E\u003Cp\u003E在传统的3D游戏中,十字准星被设置为空间中的固定点,比如通常是屏幕的中央。但是在VR中使用十字准星变得非常复杂:当用户在VR环境中四处观望时,双眼将汇集在靠近摄像机的物体上。如果十字准星处在一个固定的位置,那么用户会看到两个准星:我们在现实世界里面可以轻易模仿这种效果。把某个手指放在眼睛前面,然后聚焦到近处和远处的物体上。当我们聚焦在这个手指上时,就会看到两个背景,反之亦然。这就是传说中的\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FDiplopia%23Voluntary\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EDiplopia\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 现象。\u003C\u002Fp\u003E\u003Cp\u003E为了避免用户在查看周围环境和注视不同距离的物体时看到两个准星,我们需要将准星放到3D空间的同一个点,也就是用户所关注对象的表面。\u003C\u002Fp\u003E\u003Cp\u003E将准星放在空间的这个点意味着从远处看准星将非常小,当靠近时会变大。为了让准星的大小不随距离发生变化,我们需要根据它到摄像机的距离对其进行缩放。\u003C\u002Fp\u003E\u003Cp\u003E为了说明这一点,我们从Examples\u002FReticle场景中找了一些例子,展示了处于不同距离和比例的准星。\u003C\u002Fp\u003E\u003Cp\u003E准星放置在靠近摄像机的物体上:\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F5f0d3d86fa_b.png\& data-rawwidth=\&700\& data-rawheight=\&423\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002F5f0d3d86fa_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='423'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&423\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002F5f0d3d86fa_r.png\& data-actualsrc=\&https:\u002F\\u002F5f0d3d86fa_b.png\&\u003E\u003Cp\u003E准星放置在稍远的物体上:\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F4aef2f4a17b48875fef31cf_b.png\& data-rawwidth=\&700\& data-rawheight=\&426\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002F4aef2f4a17b48875fef31cf_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='426'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&426\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002F4aef2f4a17b48875fef31cf_r.png\& data-actualsrc=\&https:\u002F\\u002F4aef2f4a17b48875fef31cf_b.png\&\u003E\u003Cp\u003E准星放置在远处:\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fd58ba828591ccdc7e781aa96a0772ba2_b.png\& data-rawwidth=\&700\& data-rawheight=\&426\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002Fd58ba828591ccdc7e781aa96a0772ba2_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='426'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&426\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002Fd58ba828591ccdc7e781aa96a0772ba2_r.png\& data-actualsrc=\&https:\u002F\\u002Fd58ba828591ccdc7e781aa96a0772ba2_b.png\&\u003E\u003Cbr\u003E\u003Cp\u003E根据所处的位置和自身比例,用户在任何距离上看到的准星大小都是相同的。\u003C\u002Fp\u003E\u003Cp\u003E如果没有击中任何对象,那么我们只需把准星放到一个预设的距离上。在室外环境中,可能会放在摄像机的Far clip plane前面,在室内场景中可能会近得多。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E将十字准星渲染到其它游戏对象的表面\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E如果十字准星恰好和某个对象的位置相同,那么准星可能会嵌入到临近的对象中。\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Ff858b6d2edab3b5c69647_b.png\& data-rawwidth=\&473\& data-rawheight=\&466\& class=\&origin_image zh-lightbox-thumb\& width=\&473\& data-original=\&https:\u002F\\u002Ff858b6d2edab3b5c69647_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='473'%20height='466'&&\u002Fsvg&\& data-rawwidth=\&473\& data-rawheight=\&466\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&473\& data-original=\&https:\u002F\\u002Ff858b6d2edab3b5c69647_r.png\& data-actualsrc=\&https:\u002F\\u002Ff858b6d2edab3b5c69647_b.png\&\u003E\u003Cp\u003E为了解决这个问题,我们需要确保将准星渲染到场景中所有对象的前面。在VR Samples中,我们提供了一个shader,基于Unity现有的名为UIOverlay.shader的”UI\u002FUnlit\u002FText” shader。在选择某个材质的shader时,可以在”UI\u002FOverlay”中找到。\u003C\u002Fp\u003E\u003Cp\u003E这个shader对UI 元素和文本都适用,会在场景中其它物体的前面绘制。\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F3b64ff60a70be060712e_b.png\& data-rawwidth=\&473\& data-rawheight=\&466\& class=\&origin_image zh-lightbox-thumb\& width=\&473\& data-original=\&https:\u002F\\u002F3b64ff60a70be060712e_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='473'%20height='466'&&\u002Fsvg&\& data-rawwidth=\&473\& data-rawheight=\&466\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&473\& data-original=\&https:\u002F\\u002F3b64ff60a70be060712e_r.png\& data-actualsrc=\&https:\u002F\\u002F3b64ff60a70be060712e_b.png\&\u003E\u003Cp\u003E\u003Cb\u003E将准星和场景中的游戏对象对齐\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E我们希望准星的旋转方向和它所命中的对象的法线相匹配。通过RaycastHit.normal就可以实现这一点,以下是具体的实现代码:\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Epublic void SetPosition (RaycastHit hit)\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
m_ReticleTransform.position = hit.\u003C\u002Fp\u003E\u003Cp\u003E
m_ReticleTransform.localScale = m_OriginalScale * hit.\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F If the reticle should use the normal of what has been hit...\u003C\u002Fp\u003E\u003Cp\u003E
if (m_UseNormal)\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F ... set it's rotation based on it's forward vector facing along the normal.\u003C\u002Fp\u003E\u003Cp\u003E
m_ReticleTransform.rotation = Quaternion.FromToRotation (Vector3.forward, hit.normal);\u003C\u002Fp\u003E\u003Cp\u003E
else\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F However if it isn't using the normal then it's local rotation should be as it was originally.\u003C\u002Fp\u003E\u003Cp\u003E
m_ReticleTransform.localRotation = m_OriginalR\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003E我们可以在Maze场景中看到这个action。\u003C\u002Fp\u003E\u003Cp\u003E下图展示了准星如何匹配墙壁的法线:\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F604b6cf5d9bae9ab71db8b0ad581c19e_b.png\& data-rawwidth=\&700\& data-rawheight=\&447\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002F604b6cf5d9bae9ab71db8b0ad581c19e_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='447'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&447\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002F604b6cf5d9bae9ab71db8b0ad581c19e_r.png\& data-actualsrc=\&https:\u002F\\u002F604b6cf5d9bae9ab71db8b0ad581c19e_b.png\&\u003E\u003Cp\u003E下图展示了准星如何匹配地板的法线:\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Ff7a742f28d07d0fc5ace07_b.png\& data-rawwidth=\&700\& data-rawheight=\&447\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002Ff7a742f28d07d0fc5ace07_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='447'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&447\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002Ff7a742f28d07d0fc5ace07_r.png\& data-actualsrc=\&https:\u002F\\u002Ff7a742f28d07d0fc5ace07_b.png\&\u003E\u003Cp\u003E我们还提供了一个示例的Reticle脚本。该脚本可以跟VREyeRaycaster一起适用,从而将准星放置到场景的正确位置,并且可以选择跟所命中的对象法线帖齐。\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F3d1bec7536639edf9e5c_b.png\& data-rawwidth=\&469\& data-rawheight=\&126\& class=\&origin_image zh-lightbox-thumb\& width=\&469\& data-original=\&https:\u002F\\u002F3d1bec7536639edf9e5c_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='469'%20height='126'&&\u002Fsvg&\& data-rawwidth=\&469\& data-rawheight=\&126\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&469\& data-original=\&https:\u002F\\u002F3d1bec7536639edf9e5c_r.png\& data-actualsrc=\&https:\u002F\\u002F3d1bec7536639edf9e5c_b.png\&\u003E\u003Cp\u003E以上内容都可以在VRSampleScens\u002FScens\u002FExamples\u002F中看到。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E在VR项目中头部的旋转和位置\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E 在头戴设备中跟踪头部的旋转和位置可以用沉浸式的体验来感受周围环境,但同时也可以让对象根据这些数值所相应的相应。\u003C\u002Fp\u003E\u003Cp\u003E为了获取这些数值我们需要用到VR.InputTracking类,并指定我们要访问的VRNode。为了获取头部的旋转,我们会希望用到VRNode.Head,而不是两只眼睛。想了解更多的信息,可以参考Getting Started with VR Development一文中的Camera Nodes。\u003C\u002Fp\u003E\u003Cp\u003E使用头部旋转作为输入方式的可能应用是精细旋转菜单或是其它对象。在VRSampleScenes\u002FExamples\u002FRotation场景中可以看到这一点的示例。\u003C\u002Fp\u003E\u003Cp\u003E下面是ExampleRotation的脚本:\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Store the Euler rotation of the gameobject.\u003C\u002Fp\u003E\u003Cp\u003Evar eulerRotation = transform.rotation.eulerA\u003C\u002Fp\u003E\u003Cp\u003E\u002F\u002F Set the rotation to be the same as the user's in the y axis.\u003C\u002Fp\u003E\u003Cp\u003EeulerRotation.x = 0;\u003C\u002Fp\u003E\u003Cp\u003EeulerRotation.z = 0;\u003C\u002Fp\u003E\u003Cp\u003EeulerRotation.y = InputTracking.GetLocalRotation(VRNode.Head).eulerAngles.y;\u003C\u002Fp\u003E\u003Cp\u003E下面的图展示了游戏对象如何根据用户所注视的位置来进行旋转:\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fcbada17e4ac5df_b.png\& data-rawwidth=\&700\& data-rawheight=\&425\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002Fcbada17e4ac5df_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='425'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&425\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002Fcbada17e4ac5df_r.png\& data-actualsrc=\&https:\u002F\\u002Fcbada17e4ac5df_b.png\&\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002Fdfa0faa64b407_b.png\& data-rawwidth=\&700\& data-rawheight=\&426\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002Fdfa0faa64b407_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='426'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&426\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002Fdfa0faa64b407_r.png\& data-actualsrc=\&https:\u002F\\u002Fdfa0faa64b407_b.png\&\u003E\u003Cp\u003E在Flyer游戏场景中,我们将看到太空飞船基于头部的旋转来调整自身位置,具体参考FlyerMovementController:\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003EQuaternion headRotation = InputTracking.GetLocalRotation (VRNode.Head);\u003C\u002Fp\u003E\u003Cp\u003Em_TargetMarker.position = m_Camera.position + (headRotation * Vector3.forward) * m_DistanceFromC\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F18e2893daabcaeb83a37f4da_b.png\& data-rawwidth=\&700\& data-rawheight=\&350\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&https:\u002F\\u002F18e2893daabcaeb83a37f4da_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='700'%20height='350'&&\u002Fsvg&\& data-rawwidth=\&700\& data-rawheight=\&350\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&700\& data-original=\&https:\u002F\\u002F18e2893daabcaeb83a37f4da_r.png\& data-actualsrc=\&https:\u002F\\u002F18e2893daabcaeb83a37f4da_b.png\&\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E在VR游戏中使用触摸板和键盘进行交互\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cbr\u003E\u003Cp\u003EGear VR在头戴设备的侧边配备了一个触摸板。Unity把这个触摸板当做鼠标来使用,所以我们可以使用以下方法:\u003C\u002Fp\u003E\u003Cp\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002FScriptReference\u002FInput-mousePosition.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EUnity - Scripting API:\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E
Input.mousePosition\u003C\u002Fp\u003E\u003Cp\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002FScriptReference\u002FInput.GetMouseButtonDown.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EUnity - Scripting API:\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E Input.GetMouseButtonDown\u003C\u002Fp\u003E\u003Cp\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002FScriptReference\u002FInput.GetMouseButtonUp.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EUnity - Scripting API:\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E
Input.GetMouseButtonUp\u003C\u002Fp\u003E\u003Cp\u003E在使用Gear VR时,开发者可能会希望从触摸板中获取swipe数据。我们提供了一个名为VRInput的示例脚本,可以处理swipe,触碰和双触。此外它还支持方向键和键盘上的左Ctrl键(在Unity中的默认输入术语是Fire1),或者是鼠标上的左键,以此来处罚swipe和触摸。\u003C\u002Fp\u003E\u003Cp\u003E在Unity Editor中,我们可能会希望使用DK2来测试Gear VR的内容。因为目前暂时无法直接从Unity直接关联到Gear VR进行测试。考虑到Gear VR的触摸板作用跟鼠标类似,我们可以考虑使用鼠标来模拟输入。当用户佩戴HMD设备时操控键盘会更容易,因此VRInput同时也会讲方向键操作处理成swipe,将Left-Ctrl(Fire1)处理成触碰。\u003C\u002Fp\u003E\u003Cp\u003E在使用游戏手柄时,左侧的stick可以用作swipe,其中的某个按键可以用作触碰。\u003C\u002Fp\u003E\u003Cp\u003E关于如何处理swipe,可以参考VRSampleScenes\u002FScenes\u002FExamples\u002FTouchpad\u003C\u002Fp\u003E\u003Cp\u003E以下是ExampleTouchpad脚本,其中根据swipe的方向将AddTorque方法作用于一个刚体,从而让对象旋转。\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Eusing UnityE\u003C\u002Fp\u003E\u003Cp\u003Eusing VRStandardAssets.U\u003C\u002Fp\u003E\u003Cp\u003Enamespace VRStandardAssets.Examples\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F This script shows a simple example of how\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F swipe controls can be handled.\u003C\u002Fp\u003E\u003Cp\u003E
public class ExampleTouchpad : MonoBehaviour\u003C\u002Fp\u003E\u003Cp\u003E
{\u003C\u002Fp\u003E\u003Cp\u003E
[SerializeField] private float m_Torque = 10f;\u003C\u002Fp\u003E\u003Cp\u003E
[SerializeField] private VRInput m_VRI
\u003C\u002Fp\u003E\u003Cp\u003E
[SerializeField] private Rigidbody m_R
\u003C\u002Fp\u003E\u003Cp\u003E
private void OnEnable()\u003C\u002Fp\u003E\u003Cp\u003E
{\u003C\u002Fp\u003E\u003Cp\u003E
m_VRInput.OnSwipe += HandleS\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E
private void OnDisable()\u003C\u002Fp\u003E\u003Cp\u003E
{\u003C\u002Fp\u003E\u003Cp\u003E
m_VRInput.OnSwipe -= HandleS\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E
\u002F\u002FHandle the swipe events by applying AddTorque to the Ridigbody\u003C\u002Fp\u003E\u003Cp\u003E
private void HandleSwipe(VRInput.SwipeDirection swipeDirection)\u003C\u002Fp\u003E\u003Cp\u003E
{\u003C\u002Fp\u003E\u003Cp\u003E
switch (swipeDirection)\u003C\u002Fp\u003E\u003Cp\u003E
{\u003C\u002Fp\u003E\u003Cp\u003E
case VRInput.SwipeDirection.NONE:\u003C\u002Fp\u003E\u003Cp\u003E
\u003C\u002Fp\u003E\u003Cp\u003E
case VRInput.SwipeDirection.UP:\u003C\u002Fp\u003E\u003Cp\u003E
m_Rigidbody.AddTorque(Vector3.right * m_Torque);\u003C\u002Fp\u003E\u003Cp\u003E
\u003C\u002Fp\u003E\u003Cp\u003E
case VRInput.SwipeDirection.DOWN:\u003C\u002Fp\u003E\u003Cp\u003E
m_Rigidbody.AddTorque(-Vector3.right * m_Torque);\u003C\u002Fp\u003E\u003Cp\u003E
\u003C\u002Fp\u003E\u003Cp\u003E
case VRInput.SwipeDirection.LEFT:\u003C\u002Fp\u003E\u003Cp\u003E
m_Rigidbody.AddTorque(Vector3.up * m_Torque);\u003C\u002Fp\u003E\u003Cp\u003E
\u003C\u002Fp\u003E\u003Cp\u003E
case VRInput.SwipeDirection.RIGHT:\u003C\u002Fp\u003E\u003Cp\u003E
m_Rigidbody.AddTorque(-Vector3.up * m_Torque);\u003C\u002Fp\u003E\u003Cp\u003E
\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003EVR Samples项目中的VRInput示例\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E正如上面所提到的,我们所有的示例游戏都使用VRInput来处理触摸屏和键盘的输入。Maze游戏中的摄像机也会对swipe作出响应:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003EMaze\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E在这个场景中,CameraOrbit对swipe进行监听,从而允许对视点进行调整:\u003C\u002Fp\u003E\u003Cp\u003EC#脚本:\u003C\u002Fp\u003E\u003Cp\u003Eprivate void OnEnable ()\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
m_VrInput.OnSwipe += HandleS\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cp\u003Eprivate void HandleSwipe(VRInput.SwipeDirection swipeDirection)\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F If the game isn't playing or the camera is fading, return and don't handle the swipe.\u003C\u002Fp\u003E\u003Cp\u003E
if (!m_MazeGameController.Playing)\u003C\u002Fp\u003E\u003Cp\u003E\u003C\u002Fp\u003E\u003Cp\u003E
if (m_CameraFade.IsFading)\u003C\u002Fp\u003E\u003Cp\u003E\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F Otherwise start rotating the camera with either a positive or negative increment.\u003C\u002Fp\u003E\u003Cp\u003E
switch (swipeDirection)\u003C\u002Fp\u003E\u003Cp\u003E
{\u003C\u002Fp\u003E\u003Cp\u003E
case VRInput.SwipeDirection.LEFT:\u003C\u002Fp\u003E\u003Cp\u003E
StartCoroutine(RotateCamera(m_RotationIncrement));\u003C\u002Fp\u003E\u003Cp\u003E\u003C\u002Fp\u003E\u003Cp\u003E
case VRInput.SwipeDirection.RIGHT:\u003C\u002Fp\u003E\u003Cp\u003E
StartCoroutine(RotateCamera(-m_RotationIncrement));\u003C\u002Fp\u003E\u003Cp\u003E\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E}\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E如果想了解为什么场景中的摄像机按照某个轨道运行,而不是旋转迷宫本身,可以参考\u003Ca href=\&http:\u002F\\u002F?target=http%3A\\u002Flearn\u002Ftutorials\u002Ftopics\u002Fvirtual-reality\u002Fmovement-vr\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EUnity - Movement in VR\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E这篇文章。\u003C\u002Fp\u003E\u003Cp\u003E在看完本文后,我们应该对VR Sample场景中的基本交互有更深入的理解。虽然还有其它方式来实现VR交互,但这种方法是最简单易行的。在下一篇文章中,我们将讨论不同类型的VR用户界面。如果在学习中有任何问题,可以到\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002Fforums\u002Fvirtual-reality.80\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EVirtual Reality\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E中参与讨论。\u003C\u002Fp\u003E&,&updated&:new Date(&T03:13:48.000Z&),&canComment&:false,&commentPermission&:&anyone&,&commentCount&:3,&collapsedCount&:0,&likeCount&:32,&state&:&published&,&isLiked&:false,&slug&:&&,&lastestTipjarors&:[],&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\\u002F7ad35cf7b1ad7a9a8ba410_r.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&reviewers&:[],&topics&:[],&adminClosedComment&:false,&titleImageSize&:{&width&:666,&height&:444},&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&column&:{&slug&:&kidscoding&,&name&:&笨猫快乐学编程&},&tipjarState&:&activated&,&tipjarTagLine&:&真诚赞赏,手留余香&,&sourceUrl&:&&,&pageCommentsCount&:3,&tipjarorCount&:0,&annotationAction&:[],&hasPublishingDraft&:false,&snapshotUrl&:&&,&publishedTime&:&T11:13:48+08:00&,&url&:&\u002Fp\u002F&,&lastestLikers&:[{&bio&:&HCI18fall ,可以私信我一起交流啊&,&isFollowing&:false,&hash&:&8afd910f04cb9df9a4e3&,&uid&:88,&isOrg&:false,&slug&:&gao-xiao-biao&,&isFollowed&:false,&description&:&&,&name&:&Rita Gao&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fgao-xiao-biao&,&avatar&:{&id&:&v2-e749aa74c45fb961c8c7c0cf649f1eb3&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false},{&bio&:null,&isFollowing&:false,&hash&:&117b2f5c5fd&,&uid&:88,&isOrg&:false,&slug&:&yaoneil&,&isFollowed&:false,&description&:&&,&name&:&Neil Yao&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fyaoneil&,&avatar&:{&id&:&fb0ce654d&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false},{&bio&:&幻想本无形,吾等形之&,&isFollowing&:false,&hash&:&c9e7d31b1e5fc7aba17fb0bd88ca591c&,&uid&:743000,&isOrg&:false,&slug&:&wang-xiao-jian-48-30&,&isFollowed&:false,&description&:&混蛋一个&,&name&:&王小贱&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fwang-xiao-jian-48-30&,&avatar&:{&id&:&faa60ab67f584c80ed87&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false},{&bio&:&看完b乎怀疑人生&,&isFollowing&:false,&hash&:&ccdd62dfdd5b14bf0b75a5cd&,&uid&:001200,&isOrg&:false,&slug&:&ban-tai-63&,&isFollowed&:false,&description&:&有了实力再来混b乎&,&name&:&Tim Huang&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fban-tai-63&,&avatar&:{&id&:&v2-6a4552dcec73cde49bc3&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false},{&bio&:&&,&isFollowing&:false,&hash&:&afcaea9d3&,&uid&:48,&isOrg&:false,&slug&:&jyin-shi&,&isFollowed&:false,&description&:&不要相信那些高票答案!&,&name&:&人格分裂男&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fjyin-shi&,&avatar&:{&id&:&v2-492dd108bcb7f8f70fdafa12&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false}],&summary&:&\u003Cimg src=\&https:\u002F\\u002F6a51cf1edcc7d0x112.png\& data-rawwidth=\&599\& data-rawheight=\&178\& class=\&origin_image inline-img zh-lightbox-thumb\& data-original=\&https:\u002F\\u002F6a51cf1edcc7d_r.png\&\u003E\u003Cb\u003E概览:\u003C\u002Fb\u003E在VR项目中,我们需要在用户”凝视“某个物体时将其激活。在VRSamples中,我们构建了一个简单的,可拓展的轻度系统,让用户跟场景中的物体进行交互。其中包含了三个主要的脚本文件:VREyeRaycaster,VRInput和VRInteractiveItem,下面将对这三个重要的…&,&reviewingCommentsCount&:0,&meta&:{&previous&:{&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\\u002F50\u002Ffa920c8a5a3bf4dc582c_xl.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&Apple,SF,Psychology&,&isFollowing&:false,&hash&:&4c9dd7ce259e3e6ae2f0fa6ca42801ee&,&uid&:00,&isOrg&:false,&slug&:&eseedo&,&isFollowed&:false,&description&:&Create a world like Caprica.&,&name&:&王寒&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Feseedo&,&avatar&:{&id&:&7dd67dbfe&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false},&column&:{&slug&:&kidscoding&,&name&:&笨猫快乐学编程&},&content&:&\u003Cp\u003E欢迎继续我们的学习。\u003C\u002Fp\u003E\u003Cp\u003E北京时间日凌晨,Oculus正式开放对首款消费版Rift产品CV1的预订。599刀的价格让很多VR粉丝心头一紧,不过想想第一代iPhone的价格也是这样,只能期待后续的版本降价了。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E筑基\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E为了准备好学习使用Unity开发VR应用,我们首先要检查下自己的电脑硬件和软件配置是否满足要求。简单来说,显卡要NVIDIA GTX970或AMD290以上,CPU要Intel i5-459以上,内存8GB以上,要有两个USB3.0接口,一个USB2.0接口,一个HDMI 1.3接口。\u003C\u002Fp\u003E\u003Cp\u003E操作系统比较坑爹,不支持Mac,也不支持Linux。支持Win7,Win8,Win10。\u003C\u002Fp\u003E\u003Cp\u003E当然,还要把自己的显卡驱动升级到最新版本。\u003C\u002Fp\u003E\u003Cp\u003EOculus官方的检测地址:\u003C\u002Fp\u003E\u003Cp\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\u002Foculus.us5.\u002Ftrack\u002Fclick%3Fu%3D88dbdcbf84bbc2e%26id%3Db436d0da47%26e%3D86f0296884\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\u003Eoculus.us5.\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u002Ftrack\u002Fclick?u=88dbdcbf84bbc2e&id=b436d0da47&e=86f3C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003E关于电脑配置的相关信息,可以参考:\u003C\u002Fp\u003E\u003Cp\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002F\u002F06\u002Foculus-rift%25E6%E5%25A4%25A9%25E5%25BC%%2590%25AF%25E9%25A2%%25AE%25A2%25EF%25BC%258C%25E4%25BD%25A0%25E7%259A%%%25E8%E9%E7%25BD%25AE%25E5%25A4%259F%25E4%25B8%258D%25EF%25BC%259F\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EOculus Rift明天开启预订,你的电脑配置够不?(新增官方检测工具地址)\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003E一旦完成了这种烧钱的工作,就该安装Unity了。注意在打开Unity前要把DK2连接好并开启。 在继续之前,打开Oculus Configuration Utility应用,并检查Demo Scene可以正常运行。注意在运行Demo Scene之前看可能需要在Oculus Configuration Utility中设置一个新用户。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E创建第一个VR项目\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E接下来我们将使用Unity创建一个简单的VR项目demo,其效果是在VR头盔中观察一个立方体。如果你想研究更多VR示例,不妨下载我们在上一篇教程中提到的VR示例项目(\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\u002Fwww.\u002F%23%21\u002Fcontent\u002F51519\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EAsset Store\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E)。\u003C\u002Fp\u003E\u003Cimg src=\&http:\u002F\\u002F6d1c5fd0c3f631d755eca5d00cbf4370_b.png\& data-rawwidth=\&1017\& data-rawheight=\&678\& class=\&origin_image zh-lightbox-thumb\& width=\&1017\& data-original=\&http:\u002F\\u002F6d1c5fd0c3f631d755eca5d00cbf4370_r.png\&\u003E\u003Cp\u003EStep 1.\u003C\u002Fp\u003E\u003Cp\u003E打开Unity,创建一个新的空项目。\u003C\u002Fp\u003E\u003Cp\u003E说明一下,我当前用的Unity版本是5.3.1f1,可能你看到这篇教程的时候又已经升级换代了。\u003C\u002Fp\u003E\u003Cp\u003EStep 2.\u003C\u002Fp\u003E\u003Cp\u003E在Unity的菜单中选择Fiel- Build Settings,并选中PC,Mac& Linux Standalone\u003C\u002Fp\u003E\u003Cimg src=\&http:\u002F\\u002F86b9fd9e81c9c853f1ae02e2_b.png\& data-rawwidth=\&551\& data-rawheight=\&593\& class=\&origin_image zh-lightbox-thumb\& width=\&551\& data-original=\&http:\u002F\\u002F86b9fd9e81c9c853f1ae02e2_r.png\&\u003E\u003Cp\u003EStep 3.\u003C\u002Fp\u003E\u003Cp\u003E在场景中创建一个新的立方体,从菜单中选择Game Object - 3D Object -Cube ,通过Translate工具把立方体放到默认的Main Camera 前面,类似下面。\u003C\u002Fp\u003E\u003Cimg src=\&http:\u002F\\u002F55fcb10ef9b74bffd03d734_b.png\& data-rawwidth=\&700\& data-rawheight=\&659\& class=\&origin_image zh-lightbox-thumb\& width=\&700\& data-original=\&http:\u002F\\u002F55fcb10ef9b74bffd03d734_r.png\&\u003E\u003Cp\u003EStep 4.保存界面(File- Save Scene,或是使用快捷键)。\u003C\u002Fp\u003E\u003Cp\u003EStep 5.在菜单中选择Edit- Project Settings - Player,在”Other Settings“部分勾选”Virtual Reality Supported”\u003C\u002Fp\u003E\u003Cimg src=\&http:\u002F\\u002Ffe0c4bd654cfdfce7329800_b.png\& data-rawwidth=\&354\& data-rawheight=\&769\& class=\&content_image\& width=\&354\&\u003E\u003Cp\u003EStep 6.点击Unity界面上的Play按钮进入Play模式。\u003C\u002Fp\u003E\u003Cp\u003E如果之前的设置没有问题,现在你应该可以通过DK2看到这个场景,四处看看,Unity中的摄像机将自动根据DK2的位置和旋转变化反应。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E出错了怎么办?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E如果你没有在DK2中看到期望的场景,那么检查以下的事项:\u003C\u002Fp\u003E\u003Cp\u003E1.确保你在打开Unity项目前就已经把DK2接好并且开启了。\u003C\u002Fp\u003E\u003Cp\u003E2.打开Oculus自带的Oculus Configuration Utility,看看Demo Scene是不是可以正常运作\u003C\u002Fp\u003E\u003Cp\u003E3.更新你的显卡驱动到最新版本\u003C\u002Fp\u003E\u003Cp\u003E4.确保你在电脑上装了最新的Oculus Runtime 0.8,或更高版本。\u003C\u002Fp\u003E\u003Cp\u003E当然,如果还是有问题,可以到论坛里面参与讨论。\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002Fforums\u002Fvirtual-reality.80\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EVirtual Reality\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E关于VR开发的一些有用信息:\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E虽然VR应用开发和标准Unity应用开发很相似,不过还是有些区别需要注意的。\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E1.编辑器中显示的帧速(Frame rate)\u003C\u002Fp\u003E\u003Cp\u003E当你通过编辑器查看项目时,注意体验上可能有些延迟,因为电脑需要将同样的内容渲染两次。所以在实际测试项目的时候,最好创建一个可执行版本,在测试设备上实际体验。\u003C\u002Fp\u003E\u003Cp\u003E2.摄像机的移动\u003C\u002Fp\u003E\u003Cp\u003E注意,我们不能在Unity中直接移动VR摄像机。如果你希望调整摄像机的位置和旋转,需要确保将它设置为其它游戏物体GameObject的子物体,然后通过所依附的物体进行移动。\u003C\u002Fp\u003E\u003Cimg src=\&http:\u002F\\u002Fceb14ddb96c33_b.png\& data-rawwidth=\&124\& data-rawheight=\&74\& class=\&content_image\& width=\&124\&\u003E\u003Cp\u003E关于这一点,可以查看VR Samples项目中的Flyer和Maze场景。\u003C\u002Fp\u003E\u003Cp\u003E3.相机节点\u003C\u002Fp\u003E\u003Cp\u003E左眼和右眼的摄像机并不是由Unity创建的。如果你在开发中需要获取这些节点的位置,则必须使用InputTracking类。\u003C\u002Fp\u003E\u003Cp\u003E如果你想要获取场景中眼睛的不同位置(比如测试时),请使用下面的示例脚本,并将其attach到摄像机上。\u003C\u002Fp\u003E\u003Cp\u003EC#脚本\u003C\u002Fp\u003E\u003Cp\u003Eusing UnityE\u003C\u002Fp\u003E\u003Cp\u003Eusing UnityEngine.VR;\u003C\u002Fp\u003E\u003Cp\u003Epublic class UpdateEyeAnchors : MonoBehaviour\u003C\u002Fp\u003E\u003Cp\u003E{\u003C\u002Fp\u003E\u003Cp\u003E
GameObject[] eyes = new GameObject[2];\u003Cbr\u003E
string[] eyeAnchorNames ={ \&LeftEyeAnchor\&, \&RightEyeAnchor\& };void Update()\u003C\u002Fp\u003E\u003Cp\u003E
\u003Cbr\u003E
for (int i = 0; i & 2; ++i)\u003C\u002Fp\u003E\u003Cp\u003E
{\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F If the eye anchor is no longer a child of us, don't use it\u003C\u002Fp\u003E\u003Cp\u003E
if (eyes[i] != null && eyes[i].transform.parent != transform)\u003C\u002Fp\u003E\u003Cp\u003E
{\u003C\u002Fp

我要回帖

更多关于 小东想知道火炉的温度 的文章

 

随机推荐