UNITY开发VR眼镜中文入门教程(5)

VR中的运动

 

除了达到帧率的要求外,在VR中运动也是个要素,在策划游戏的阶段就要好好思考这个问题,如果选择的运动解决方案会引起眩晕甚至恶心,将严重影响你的项目.

VR中的恶心和舒适

 

玩游戏感觉恶心,也被称为VR病(https://en.wikipedia.org/wiki/Virtual_reality_sickness),这是因为在真实的世界中玩家的身体是固定的,当他们以虚拟的视角去查看移动的虚拟环境,就很可能让身体感受到不适.

一般情况下,应避免移动相机,除非是跟随用户运动而动,简单来说头戴式显示设备把虚拟的信号从眼睛或者耳朵传递给玩家,使得玩家认为它是真实的,比如场景中不停的旋转,玩家的大脑会认为身体真的在旋转,这是人的神经系统就会做出排斥反应,最后导致眩晕,恶心等不舒适的情况.不过也有例外,所以要多实验和测试,尽可能的让多样的玩家来感受,找到一个权衡的舒适的操控方案.如果玩家的身体能实际跟随相机的移动,那么会极大的减弱不适感,比如有空间跟踪技术的HTC Vive.但这仍然依赖我们要为用户开发没有真实的移动玩家环境,迷惑视觉听觉找一个平衡点.

目前位置静止的VR体验是最舒适的,通常只需要用户原地不动,通过旋转或者转头来操作游戏,VR示例中的180度射击及360度射击就是这种风格的游戏.

VR中的第一人称射击游戏

传统的鼠标和WSAD或游戏手柄控制的第一人称游戏经常引起恶心不适感,所以最好避免这种操作.如果你决定要开发第一人称控制的游戏,要请尽可能多的人试玩游戏并反馈给你改进的建议,绝对要禁用使用点头等快速移动视角的动作.我们捕捉头部的旋转赋给相机(https://twitter.com/id_aa_carmack/status/553238861267353600).可以看CameraOrbit组件学习相机淡出渐入及捕捉旋转.

如果要执行运动操作,我们建议给玩家一个恒定的静态视觉参考体,比如驾驶舱,客舱,汽车内部,可以参考这几个游戏:Radial-G(radial-g.com/), Lunar Flight(www.shovsoft.com/lunarflight/), and Titans of Space(www.titansofspacevr.com/).

在VR中用淡出/闪烁转换场景

在虚拟场景快速跳转相机位置较流行的方法是用淡出,即要跳转位置前渐渐的将画面黑掉,然后将相机移动到所需的位置或场景再快速的淡出黑色显示出虚拟场景.另外一种方法稍复杂一些,有点想相机快门,用两个黑色的挡板开合作为遮挡来快速跳转相机位置,Tom Forsyth在Oculus2014大会视频上有介绍这个方式,可以翻墙看看这个视频:https://www.youtube.com/watch?v=addUnJpjjv4&feature=youtu.be&t=40m5s

在VR示例场景中运动

 

正如我们上面说过的,我们不要直接在Unity中移动相机位置,相反我们必须给相机设定一个父对象,并把对相机的移动或旋转应用到父对象.

2_cameracontainer

我们想确保用户有一个舒适的VR体验,在我们提供的VR示例中,大多数场景都不包含运动的相机,而只去让迷宫的沙盒及飞行器运动.早VR这一新媒介早期阶段我们希望给用户一个积极向好的期望,才能有利于VR事业的发展.

Flyer游戏中的运动

 

Flyer示例中的相机从菜单消失后直接以恒定的速度运动着,玩家并不经历从静止到加速的过程,静止到加速的过程通畅会引起恶心不适感.

3_flyervideo01

随着从飞机旁边略过的圆圈以及移动的小行星等效果,可以给人一种移动的感觉.同时也允许环视周围,因为能看到周围所以能减少恶心不适感.

可以用类似的效果实现固定相机,并移动一切相对于相机的对象.

Maze – VR中的桌游

 

迷宫这个例子提供了俯视风格的桌游效果,看起来就像把相机位置固定,但是让迷宫沙盘旋转起来.

4_mazerotatevideo

然而我们用了光照贴图和导航网格,它们被标记成了静态,所以我们不能去旋转迷宫沙盘,相反,我们要改变成如下的层级:

5_maze-camera-hierarchy

VROrbitCamera 对象被放置在迷宫沙盘的中心,MazeUnityLogo 物体在迷宫沙盘的一边,MainCamera在另一边.

6_mazerotatesceneview

我们旋转VROrbitCamera对象,因为它的旋转中心在迷宫中心,静止的Unity Logo作为标识参考,让我们认为是沙盘在旋转.

完成这个旋转,VROrbitCamera有两个组件:

CameraOrbit处理旋转

Rigidbody让我们用来改变质量和阻尼等参数

7_cameraorbit

CameraOrbit 组件有三种旋转样式选项:

8_cameraorbit-enum

Smooth – 我们用了Smooth这个选项来让旋转变得顺畅,慢慢降低滑动速度,改变旋转增量和刚体的特性实现对相机运动速度,阻尼的调整. Step – 有时候我们需要立刻旋转相机,去掉中间插值过程,也就是我们滑动多少,相机就转多少,完全同步的旋转.

Step With Fade – 和Step类似,但它用了一个非常快的淡出,当滑动触摸板时,画面黑掉,相机在后面快速的移动到对应的位置,这样会减少恶心不适感.改变Rotation Fade Duration会改变淡出持续的时间.

9_stepwithfadevideo

考虑到VR正在快速发展中,要移动,又要避免恶心不适感,我们强烈建议您认真阅读Oculus的手册关于”Simulator Sickness(https://developer.oculus.com/documentation/intro-vr/latest/concepts/bp_app_simulator_sickness/)” 和”Motion(https://developer.oculus.com/documentation/intro-vr/latest/concepts/bp_app_motion/)”等深入这些知识的文章.

在180/360度射击游戏中的运动

我们另外两个示例场景演示了简单的使用跟踪旋转头部控制相机运动以及简单的射击输入.周围环境是静止的,玩家的目标就是简单的凝视要射击的物体并射击.

这些场景可以说是舒适的,是最不宜引起恶心不适感的.

现在你应该有了一个基本了解为什么要这么处理场景中的运动,也可以阅读这些主题进一步学习:


原文:http://unity3d.com/learn/tutorials/topics/virtual-reality

由 四角钱 (XK) 翻译,转载请注明来自 http://blog.1vr.cn

UNITY开发VR眼镜中文入门教程(4)

VR的用户界面

 

在设计VR的用户界面时,传统的UI设计方案可能会出现一些问题,现在我们来讨论和解决VR中制作用户界面的问题.

UI的分辨率和外观

DK2的分辨率是1920 x 1080 (960 x 1080 每只眼), Gear VR 是 2560 x 1440 (1280 x 1440 每只眼),这意味着在屏幕上能看得清任何元素的像素.

特别要注意的是用户界面元素在屏幕上的大小,我们推荐使用更大的字体或者加粗字体以及避免用很细的线设计界面.

UI类型

 

非故事类

在非VR项目中,UI通常覆盖在屏幕上显示如血条等信息,我们称之为HUD(抬头显示器).这就是所谓的非故事类界面,它不真实存在,但它有利于玩家查看游戏中的信息.

这个词同样用在电影中作为非故事的声音,如电影或电视的背景音乐.

在Unity中添加HUD样式的非故事类UI是更改相机的UI Canvas渲染模式为Screen Space – Overlay或 Screen Space实现的.

 

1_screenspacecamera

2_screenspaceoverlay

而VR中通常不用这种方法,我们眼睛无法集中在很近的一个点上,而且Screen Space-Overlay是不支持的.

空间UI

相反我们通常需要在场景中呈现我们的UI,把相机改成World Space Canvas渲染模式.这将让我们的眼睛能聚焦到UI上,被称为空间界面(Spatial UI)

3_worldspace

在场景空间中放置UI也需要一些思考设计.太靠近用户会引起视觉疲劳,太远又会让用户觉得视点聚焦在地平线上,不过放置远一些是适合在户外场景中,小房间中就不适合了.还需要根据需求动态的缩放用户界面的大小.

最好在一个相对舒适的阅读距离上显示用户界面,并相应的调整它的尺寸.在Menu场景中可以看这个例子:它在面前几米远的距离,文字和图像都很大,很易于查看.

如果在某些特定距离上进行空间用户界面显示,可能会发现界面与游戏对象发生了穿插,那么请看我们前面将的如何避免穿插或直接使用VR示例中的着色器.或者使用Text的着色器.

许多开发者最初会将用户界面附加到相机上,所以当用户移动视角时,界面会始终保持在视野中的一个固定位置,这如果用来做准心是很有用的,但如果是其他较大的界面元素就会影响到玩家的观察视线,并可能导致用户恶心不适感.在360度射击游戏示例中,界面会在视图中做短暂的停留,便于用户熟悉场景环境,避免遮挡用户视野.

4_360menu

VR技术为我们提供了一个模拟360度真实环境的机会,有时我们可以需要显示给用户让用户去寻找一个特定的方向.在示例场景中,我们在场景中使用了一些箭头来提示用户找到正确的方向,如果方向在正常范围内,这淡出箭头提醒.

可以用GUIArrows预置,它们的用途就是比较头部的角度,如果头部角度超过预设角度(GUIArrows脚本里Show Angle)时变会淡入提醒用户往正确的方向看.

5_guiarrows-component

6_180shooter01

 

故事界面

空间界面的另一种实现方式就是将场景中的元素现实给用户.这可能是墙上的一个挂钟,电视机,显示器,手机,或者一个带有全息显示的未来科技枪.这就是故事UI,我们可以看下示例Flyer场景的飞船界面或者射击游戏的枪的界面.

7_diegetic-ship

8_diegetic-gun

虽然这不是严格意义上的故事界面,但在能让用户能很直观的得到游戏中想要了解的信息.

用户界面开发的深入阅读

深入分析这些类型的界面可以阅读本文Gamasutra(www.gamasutra.com/view/feature/4286/game_ui_discoveries_what_players_.php).

用户界面交互

 

利用前面VR交互中的VREyeRaycasterVRInput, 和VRInteractiveItem我们可以创建一个类来处理用户界面的交互.

在Maze场景中有一个特定的开关作为用户界面交互,在每个游戏开始前都有个阅读说明界面,可查看Oculus博客上的“Unity’s UI System in VR”,那里还提供了示例代码.

VR示例中的用户界面

 

让我们看看VR示例中用到了哪些技术制作用户界面

Menu

9_mainmenu

在场景中自定义了弯曲网格来作为用户界面.

Flyer

游戏介绍和游戏结束界面都是在世界空间里的静态界面.

10_flyer-intro-ui

然而,我们把一些重要信息放在在了飞船上,作为故事界面能让玩家随时查看到是很有意义的.

11_flyer-ui-facing_camera

这个UI会始终旋转面向镜头,这样可以避免较大的倾斜角度影响用户观看阅读界面.

Maze

在Maze场景,我们同样用世界空间里的静态界面做了游戏介绍和游戏结束画面.:

12_maze-intro

当触控滑动可用时,场景中的用户界面也被用来提示玩家进行交互.

13_maze-lookandhold

Shooter 180 (Target Gallery)

用世界空间里的静态界面做了游戏介绍和游戏结束画面:

14_target_gallery_intro

正如上面所说的,在枪上用了故事界面来显示分数和时间:

15_diegetic-gun

Shooter 360 (Target Arena)

最后,在这场景中用了空间用户界面,但有轻微扭动,当玩家环顾四周时,我们在移动用户界面中做了个短暂延迟,以满足玩家自由的环顾四周.

16_targetarena-title

同样,枪上使用了固定的用户界面:

17_targetarena-gunui

VR中为文字做抗锯齿

在场景中使用Canvas Scaler,UI就会有 “Reference Pixels Per Unit”设置项,默认为1,然后改变“Dynamic Pixels Per Unit”,知道看到文本略微柔化的边缘.在这里可以看到”Dynamic Pixels Per Unit”被设置为1.75和设置为3时的差异.设置为3时,边缘较硬,设置为1.75时,边缘会有点柔化.

18_ppu-3

19_ppu-1.75

我们现在应该可以使用 VREyeRaycasterVRInput, 和  VRInteractiveItem来创建基本的交互界面了.


 

原文:http://unity3d.com/learn/tutorials/topics/virtual-reality

由 四角钱 (XK) 翻译,转载请注明来自 http://blog.1vr.cn

UNITY开发VR眼镜中文入门教程(3)

VR中的交互

 

概述

 

在VR中我们经常需要激活用户正在看的对象,比如VRSamples中,我们内建了一个简单的可扩展的,轻量级用户交互系统框架.它包括了三个主要脚本::VREyeRaycaster, VRInput, 和 VRInteractiveItem,下面对它们进行简要的说明.

VREyeRaycaster

 

1_vreyeraycaster

这个脚本需要放置在Main Camera.在每个Update()中脚本会用 Physics.Raycast去射线给任何看到的碰撞器.当然也可以通过层(docs.unity3d.com/Manual/Layers.html)的设置做排除.也可以将所有需要互动的对象放到一个单独的层中来优化性能.

如果射线投射到了一个碰撞器,这个脚本将去找这个游戏对象上的VRInteractiveItem组件.

VRInteractiveItem interactible = hit.collider.GetComponent<VRInteractiveItem>();    //试图获得被射对象上的VRInteractiveItem组件

因此我们可以判断用户是否在看一个物体或者不再看这个物体,通过这个状态的获取再去做相应的动作.

VRInput

 

2_vrinput

VRInput 是一个简单的判断在GearVR设备中发生的单击,双击,滑动的类或DK2在PC做同样的输入.我们可以直接从VRInput中获取输入事件:

public event Action<SwipeDirection> OnSwipe;                //在每一帧中滑动或没有滑动事件时调用
public event Action OnClick;                                // 当Fire1键被触发且不是双击时调用.
public event Action OnDown;                                 // 在Fire1被按下时调用
public event Action OnUp;                                   // 在Fire1被松开时调用.
public event Action OnDoubleClick;                          // 当检测到双击事件时被调用.
public event Action OnCancel;                               // 当Cancel被触发时调用.

更多输入事件的信息请查阅(unity3d.com/ru/learn/tutorials/modules/intermediate/scripting/events).

VRInteractiveItem

 

这个组件可以添加到VR中任何希望用户交互的游戏物体上.它需要物体上附加一个碰撞器组件.

在物体上我们可以获得六种事件:

public event Action OnOver;             //当目光移到这个物体上时触发.
public event Action OnOut;              //当目光已到这个物体上时触发.
public event Action OnClick;            //当这个物体被凝视并且有点击事件时触发.
public event Action OnDoubleClick;      //当这个物体被凝视并且有双击事件时被触发.
public event Action OnUp;               //当这个物体被凝视并且松开Fire1键时被触发.
public event Action OnDown;             // 当这个物体被凝视并且按下Fire1键时被触发.

以及一个布尔值来获得当前物体是否被凝视:

public bool IsOver
{
get{ return m_IsOver;} //当前这个物体被凝视吗?
}

 

我们可以创建自己的脚本来对这些事件做出相应的反应.下面这个简单的例子演示这些事件的使用:

using UnityEngine;
using VRStandardAssets.Utils;
namespace VRStandardAssets.Examples
{
// 这是一个与物体交互的简单例子
// 被用来处理物体响应输入事件
public class ExampleInteractiveItem : MonoBehaviour
{
[SerializeField] private Material m_NormalMaterial;
[SerializeField] private Material m_OverMaterial;
[SerializeField] private Material m_ClickedMaterial;
[SerializeField] private Material m_DoubleClickedMaterial;
[SerializeField] private VRInteractiveItem m_InteractiveItem;
[SerializeField] private Renderer m_Renderer;
private void Awake ()
{
m_Renderer.material = m_NormalMaterial;
}
private void OnEnable()
{
m_InteractiveItem.OnOver += HandleOver;
m_InteractiveItem.OnOut += HandleOut;
m_InteractiveItem.OnClick += HandleClick;
m_InteractiveItem.OnDoubleClick += HandleDoubleClick;
}
private void OnDisable()
{
m_InteractiveItem.OnOver -= HandleOver;
m_InteractiveItem.OnOut -= HandleOut;
m_InteractiveItem.OnClick -= HandleClick;
m_InteractiveItem.OnDoubleClick -= HandleDoubleClick;
}
//处理当前物体
private void HandleOver()
{
Debug.Log("Show over state");
m_Renderer.material = m_OverMaterial;
}
//处理非当前物体
private void HandleOut()
{
Debug.Log("Show out state");
m_Renderer.material = m_NormalMaterial;
}
//处理单击事件
private void HandleClick()
{
Debug.Log("Show click state");
m_Renderer.material = m_ClickedMaterial;
}
//处理双击事件
private void HandleDoubleClick()
{
Debug.Log("Show double click");
m_Renderer.material = m_DoubleClickedMaterial;
}
}
}

 

关于这段脚本的完整示例请查看VR示例的VRSampleScenes/Scenes/Examples/InteractiveItem场景

环状选择框(SelectionRadial) 和 滑块选择条(SelectionSlider)

 

我们做个环状选择框及滑块选择条,让用户凝视物体并按住Fire1键实现”确定”命令的交互:

3_selectionradial

4_selectionslider

 

随着输入的持续,选择栏进行填充,并产生OnSelectionComplete 或 被填满时OnBarFilled 事件,相关代码可以在 electionRadial.cs 和SelectionSlider.cs中找到,有很详尽的注释.从用户体验上来讲让用户知道他们在做什么,能准确的确定或取消与虚拟世界的交互.

VR示例中的交互

 

现在让我们来看VR示例中包含的交互功能,了解它们是如何实现的.

Menu场景的交互

5_menu

每项菜单都有好几个组件,这里我们重点看 MenuButtonVRInteractiveItem, 和 Mesh Collider.

 

MenuButton组件用来获得在VRInteractiveItem 组件上的OnOver 和 OnOut事件.所以当视野在菜单项时,选择条将填充出现,目光不在菜单项时,选择条减小填充.当选择条完全填满并按住Fire1时将出现环状选择框开始填充:

6_selectionradial

同样的在环状选择条填满时也有OnSelectionComplete 事件,然后HandleSelectionComplete被调用,接着相机镜头淡出后载入选择的关卡.

private void OnEnable ()
{
m_InteractiveItem.OnOver += HandleOver;
m_InteractiveItem.OnOut += HandleOut;
m_SelectionRadial.OnSelectionComplete += HandleSelectionComplete;
}
private void OnDisable ()
{
m_InteractiveItem.OnOver -= HandleOver;
m_InteractiveItem.OnOut -= HandleOut;
m_SelectionRadial.OnSelectionComplete -= HandleSelectionComplete;
}
private void HandleOver()
{
// 当用户正在凝视场景菜单项时,显示环状选择条.
m_SelectionRadial.Show();
m_GazeOver = true;
}
private void HandleOut()
{
// 当用户不在凝视场景菜单项时,隐藏环状选择条.
m_SelectionRadial.Hide();
m_GazeOver = false;
}
private void HandleSelectionComplete()
{
// 当用户凝视凝视菜单项并且环状选择条填充满时激活按钮.
if(m_GazeOver)
StartCoroutine (ActivateButton());
}
private IEnumerator ActivateButton()
{
// 如果相机已经淡出则忽略
if (m_CameraFade.IsFading)
yield break;
// 在有任何按钮选择事件发生时调去它
if (OnButtonSelected != null)
OnButtonSelected(this);
// 等待相机的淡出
yield return StartCoroutine(m_CameraFade.BeginFadeOut(true));
// 载入关卡
SceneManager.LoadScene(m_SceneToLoad, LoadSceneMode.Single);
}

让我们看看环状选择框的示例,注意视野截图中心的粉红圆点.

7_radial-off

当用户凝视菜单项时可以看到还未开始填充的环状选择框.

8_radial-on

当用户继续凝视这个菜单项并且按下Fire1键,会看到环状选择框开始填充

9_radial-filling

我们建议让环状选择框和滑块选择条的时间一致,提升用户体验,以帮助用户更快的使用VR这种新媒介.

Maze场景中的交互

 

Maze游戏提供了一个桌游形式互动的例子,通过引导角色到出口再通过开关阻止炮塔的攻击(剧透了!!).

当选择一个角色,这个角色会出现一条即将行走的路线,我们可以通过滑动触控板,按下光标键或用游戏手柄的左摇杆来旋转视图.

10_maze-scene-overview

MazeFloor 物体用一个MeshCollider 和VRInteractiveItem 组件来实现交互:

11_mazefloor

MazeCourse 游戏物体作为父物体,包含了 MazeFloor 和 MazeWalls游戏对象,用于构成迷宫的布局.

12_mazecourse

有一个MazeTargetSetting 脚本在MazeCourse上并引用了MazeFloor上的VRInteractiveItem 组件.

13_mazetargetsetting

MazeTargetSetting 获取到VRInteractiveItem上的OnDoubleClick事件, 然后将调用OnTargetSet 事件,通过转换作为Transform的参数:

public event Action<Transform> OnTargetSet;                     // 当目的地设定后触发
private void OnEnable()
{
m_InteractiveItem.OnDoubleClick += HandleDoubleClick;
}
private void OnDisable()
{
m_InteractiveItem.OnDoubleClick -= HandleDoubleClick;
}
private void HandleDoubleClick()
{
// 一旦目标设定启用及获取了OnTargetSet事件就执行这个方法.
if (m_Active && OnTargetSet != null)
OnTargetSet (m_Reticle.ReticleTransform);
}

无论MazeCharacter游戏对象上的Player组件还是在MazeDestinationMarkerGUI游戏对象上的DestinationMarker组件获取到这个事件,都会做出相应的反应.

角色用导航网个系统去在迷宫中寻路.Player组件中HandleSetTarget函数被设置成 Nav Mesh Agent(docs.unity3d.com/Manual/nav-CreateNavMeshAgent.html)去响应变换位置,并更新绘制Agent的路线,让角色路径可视化:

private void HandleSetTarget(Transform target)
{
// 如果游戏没有结束则设定角色的AI和路径线
if (m_IsGameOver)
return;
m_AiCharacter.SetTarget(target.position);
m_AgentTrail.SetDestination();
}

DestinationMarker 移动标识物到准星的Transform位置.

private void HandleTargetSet(Transform target)
{
// 当目标被设定就显示标识物
Show();
// 把准星目标位置赋予标识物的位置
transform.position = target.position;
// 播放音效.
m_MarkerMoveAudio.Play();
// 播放标识物的动画
m_Animator.Play(m_HashMazeNavMarkerAnimState, -1, 0.0f);
}

可以看到被标识物目的地的准星及所选角色的行动轨迹.

14_mazevideo02

迷宫中的触发开关也是VR中常用的交互例子.本文使用碰撞器以及VRInteractiveItemSelectionSlider类来实现.

15_selectionslider-inspector

如上图所示的要接受交互对象的脚本,SelectionSlider 脚本监听来自VRInteractiveItem 和 VRInput的事件:

private void OnEnable ()
{
m_VRInput.OnDown += HandleDown;
m_VRInput.OnUp += HandleUp;
m_InteractiveItem.OnOver += HandleOver;
m_InteractiveItem.OnOut += HandleOut;
}

Flyer场景中的交互

Flyer场景是一个有时间限制游戏,玩家引导太空中的飞船躲避小行星,用Fire1键射击小行星,穿越积分圈获得积分等等.这游戏有点像飞行俱乐部和星际火狐.

在互动方面,Flyer是非常简单的;使用FlyerLaserController获取VRInput中的OnDown事件发射激光射击:

private void OnEnable()
{
m_VRInput.OnDown += HandleDown;
}
private void HandleDown()
{
//如果游戏没有运行终止执行
if (!m_GameController.IsGameRunning)
return;
// 从任意位置发射激光束
SpawnLaser(m_LaserSpawnPosLeft);
SpawnLaser(m_LaserSpawnPosRight);
}

Shooter180 和 Shooter360场景中的交互(180度第一人称射击和360度守堡式射击)

 

VR示例中有两个目标射击游戏,有点近似X战警的场景画面,一个是180度的沿着隧道行走的第一视角射击游戏,另一个是原地360度守堡式的射击游戏.

射击游戏中每个生成的靶子都有个碰撞器,VRInteractiveItem 和 ShootingTarget.

16_shootingtargetobject

17_shootingtarget

 

ShootingTarget自己获取VRInteractiveItem上的OnDown事件来判断目标是否被击中.这种方法适合用与点射,如果是连发射击,我们需要用其它方案.

我们对游戏里的基本交互做了概述以及它们在VR示例中如何用的.现在我们来讨论如何用凝视作为准星.

凝视

 

在VR中监测用户视线是非常重要的,无论是允许用户与对象进行触发动画的交互还是向目标射击.请注意”凝视(GAZE)”这个术语,后面我们会经常提到.

大多数的头戴显示设备还不支持眼球跟踪,所以我们只能用头部的朝向来估计用户的目光朝向.如前面概述中说的,我们只需在相机中心发射条射线用射线检测目光凝视什么对象就可以了.当然,这意味着任何被检测的物体都必须有个碰撞器组件.

准星

 

一个准星用来显示用户视野中心,准星的样式可以是一个简单的点或者一个十字线,这取决于你项目的风格.

传统游戏中往往会使用十字线作为准星,在VR中做准星定位是有点复杂的:用户会将眼睛的焦点放在接近于相机的物体上,那么用户会看到两个准星,我们可以把手指放在眼前模拟聚焦效果,手指离眼睛越近,背景越模糊,反之亦然,这就是所谓的自愿复视(voluntary Diplopia(https://en.wikipedia.org/wiki/Diplopia#Voluntary)).

为了避免玩家看场景时由于焦点不同出现两个准星,我们需要将准星放在玩家看的对象的表面上.

如果单单去移动准星的位置,当距离远时,准星会变得很小,为了保证准星大小不变,我们需要根据它距离相机的距离去做缩放.

为了说明这个缩放,可以查看Examples/Reticle场景,它包含了不同距离和准星缩放的示例.

准星位于相机所观察到较近的一个物体上:

18_reticle-close

准星在一个较远的物体上

19_reticle-far

准星位于更远距离的位置:

20_reticle-distance

由于定位和缩放准星,所以用户会觉得准星无论距离多远都是相同的大小,当准星没有处于场景的某个对象上时,我们只需将准星放在预订的一个距离,这个距离取决于场景大小,比如一个室外环境,我们可以把准星放置在相机远一些,而在室内场景,可能让准星距离相机更近一些.

在游戏对象上绘制准星

 

如果在物体相同位置绘制准星,那么准星可能会与游戏对象发生穿插问题:

21_unity-reticle-clipped

要解决这个问题,我们要确保准星渲染于场景中所有物体之上,这里我们用到基于Unity内置着色器”UI/Unlit/Text”改写名为UIOverlay.shader着色器.为材质选择着色器时会在”UI/Overlay”下看到它.

本场景中有两个UI控件和文本,将把它画在场景中其它物体之上:

22_unity-reticle-noclipped

对齐准星到场景中的物体

最后,我们想实现准星的旋转匹配到被附加的对象法线,我们可以用 RaycastHit.normal(docs.unity3d.com/ScriptReference/RaycastHit-normal.html),看下面的代码:

public void SetPosition (RaycastHit hit)
{
m_ReticleTransform.position = hit.point;
m_ReticleTransform.localScale = m_OriginalScale * hit.distance;
// 如果物体表面的法线可以被准星使用
if (m_UseNormal)
// ... 设定它的正向向量旋转,使其沿着法线方向
m_ReticleTransform.rotation = Quaternion.FromToRotation (Vector3.forward, hit.normal);
else
// 然后如果没有正确的法向方向可用的话就让它保持本来的朝向.
m_ReticleTransform.localRotation = m_OriginalRotation;
}

我们可以在迷宫场景中看到准星叠加到了墙体表面

23_unity-reticle-wall

这里能看到准星叠加到了地板上:

24_unity-reticle-floor

我们同样提供了完整的示例脚本来说明通过VREyeRaycaster定位准星到凝视到的物体表面.

25_reticle-inspector

以上所有内容均可在VRSampleScenes/Scenes/Examples/找到

VR中头部的旋转和位置

 

通过旋转头部,头戴式显示设备可以看周围的环境,有时候我们需要访问这个视角值.我们就需要用到 VR.InputTracking(docs.unity3d.com/ScriptReference/VR.InputTracking.html)类,并指定需要得到哪些VRNode(docs.unity3d.com/ScriptReference/VR.VRNode.html)数据.比如我们要获得头部的旋转,就要用VRNode.Head,而不是取眼睛的节点.

在示例项目中可以找到一个基于头部旋转作为菜单选择的例子,可以看VRSampleScenes/Examples/Rotation场景及ExampleRotation脚本:

// 存储游戏对象的旋转欧拉角
var eulerRotation = transform.rotation.eulerAngles;
//根据用户头部的y轴值设定对象的旋转
eulerRotation.x = 0;
eulerRotation.z = 0;
eulerRotation.y = InputTracking.GetLocalRotation(VRNode.Head).eulerAngles.y;

运行后我们就可以看到游戏对象是如何旋转的:

26_rotation-left

27_rotation-right

在Flyer游戏,我们用头部动作来控制飞船的位,线看FlyerMovementController这个脚本:

Quaternion headRotation = InputTracking.GetLocalRotation (VRNode.Head);
m_TargetMarker.position = m_Camera.position + (headRotation * Vector3.forward) * m_DistanceFromCamera;

28_flyervideo01

在VR游戏中用触控板和键盘交互

 

Gear VR的设备侧面有一块触控板,在Unity中相当于鼠标,我们可以用如下的命令:

Input.mousePosition(docs.unity3d.com/ScriptReference/Input-mousePosition.html)

Input.GetMouseButtonDown(docs.unity3d.com/ScriptReference/Input.GetMouseButtonDown.html)

Input.GetMouseButtonUp(docs.unity3d.com/ScriptReference/Input.GetMouseButtonUp.html)

在GearVR我们也可以获得滑动输入.在示例脚本VRInput中写好了关于滑动,单机,双击的输入获取.也同样支持按键盘上的左Ctrl键(Unity默认输入术语叫Fire1)或鼠标左键的鼠标滑动或鼠标单击.

而在Unity编辑器中,我们如果用DK2设备还没有很好的办法来测试Unity开发到GearVR的项目.不过我们可以用鼠标模拟触控板,配合键盘来实现测试.

左Ctrel(Fire1)作为单击,滑动鼠标模拟触控板的滑动旋转物体.

可以查看VRSampleScenes/Scenes/Examples/Touchpad场景了解上面说到的输入操作.

下面是ExampleTouchpad脚本,它依照滑动的方向给物体上的Rigidbody

以AddTorque实现旋转.

using UnityEngine;
using VRStandardAssets.Utils;
namespace VRStandardAssets.Examples
{
// 处理滑动控制的简单脚本例子
public class ExampleTouchpad : MonoBehaviour
{
[SerializeField] private float m_Torque = 10f;
[SerializeField] private VRInput m_VRInput;
[SerializeField] private Rigidbody m_Rigidbody;
private void OnEnable()
{
m_VRInput.OnSwipe += HandleSwipe;
}
private void OnDisable()
{
m_VRInput.OnSwipe -= HandleSwipe;
}
//给Ridigbody施加AddTorque来处理滑动事件
private void HandleSwipe(VRInput.SwipeDirection swipeDirection)
{
switch (swipeDirection)
{
case VRInput.SwipeDirection.NONE:
break;
case VRInput.SwipeDirection.UP:
m_Rigidbody.AddTorque(Vector3.right * m_Torque);
break;
case VRInput.SwipeDirection.DOWN:
m_Rigidbody.AddTorque(-Vector3.right * m_Torque);
break;
case VRInput.SwipeDirection.LEFT:
m_Rigidbody.AddTorque(Vector3.up * m_Torque);
break;
case VRInput.SwipeDirection.RIGHT:
m_Rigidbody.AddTorque(-Vector3.up * m_Torque);
break;
}
}
}
}

VR示例中的VRInput示例

 

如上所述,我们在示例游戏中使用VRInput处理触摸板和键盘的输入.

在迷宫游戏中,CameraOrbit监听滑动事件来响应视图的旋转.

private void OnEnable ()
{
m_VrInput.OnSwipe += HandleSwipe;
}
private void HandleSwipe(VRInput.SwipeDirection swipeDirection)
{
// 如果游戏没有开始或者正在播放相机淡出效果,不处理滑动输入.
if (!m_MazeGameController.Playing)
return;
if (m_CameraFade.IsFading)
return;
//否则根据滑动的进行相应的正转或负转.
switch (swipeDirection)
{
case VRInput.SwipeDirection.LEFT:
StartCoroutine(RotateCamera(m_RotationIncrement));
break;
case VRInput.SwipeDirection.RIGHT:
StartCoroutine(RotateCamera(-m_RotationIncrement));
break;
}
}


原文:http://unity3d.com/learn/tutorials/topics/virtual-reality

由 四角钱 (XK) 翻译,转载请注明来自 http://blog.1vr.cn

 

Unity开发VR眼镜中文入门教程(2)

VR基础开发

 

按照前面所描述的安装后软硬件环境.并在Oculus Configuration Utility运行Demo Scene场景确保DK2的连接和配置正确.

创建第一个VR项目

 

我们现在开始创建一个VR测试项目,在场景中放置立方体便于查看运行效果,可以从资源商店里下载更精美的示例场景(https://www.assetstore.unity3d.com/#!/content/51519).

第一步: 打开Unity,新建个空项目.

第二步: 确保选择的PC, Mac & Linux Standalone 平台,在File > Build Settings设置.

1_build_settings

第三步: 创建一个立方体(Game Object > 3D Object > Cube)并用移动工具把它放在默认主相机的前方.

2_basic_cube_rotated

第四步:保存场景 (File > Save Scene).

第五步:到Edit > Project Settings > Player下选”Virtual Reality Supported”复选框.

3_enable_vr_-2

第六步,点击Play按钮进入播放模式

现在可以在DK2中看到你的场景.同样的你可以在Unity的Game视图看到相同的画面.

故障排除: 如果在DK2中看不到场景,可以试试下面的方法:

  • 在打开Unity项目之前确保DK2连接好电脑并且开启电源.
  • 在Oculus Configuration Utility查看Demo场景是否正常运行.
  • 更新你的显卡驱动.
  • 确保安装了Oculus Runtime 0.8(https://developer.oculus.com/downloads/)或更新版本.

如果仍旧没有解决需要在VR开发需要援助请查看Unity的VR论坛:forum.unity3d.com/forums/virtual-reality.80/

VR开发中一些重要信息

 

VR的开发与常规Unity开发非常相似,但还是有一些差异的.

编辑器中的帧率

 

如果在编辑器中运行VR项目,可能会遇到一些延迟和抖动,由于电脑要渲染两次相同的内容,Unity编辑器界面绘制也会消耗一定资源,所以最好要偶尔把项目编译出来直接运行它来检查效率.

相机的运动

 

在Unity中不能直接移动VR相机,如果你想改变它的位置和朝向,要确保相机有一个父物体,并去移动或旋转这个父物体.

4_cameracontainer

可以查看VR示例项目中的Flyer和Maze场景我们操作移动相机的方法.

相机节点

 

Unity中是不需要创建左右眼相机的.如果你想活的左右眼相机的位置,你只能用InputTracking(docs.unity3d.com/ScriptReference/VR.InputTracking.html)类.如果你想在场景中获得左右眼相机的位置或者用来测试之类,可以用下面的脚本附加到相机上来查看.

 

using UnityEngine;
using UnityEngine.VR;
public class UpdateEyeAnchors : MonoBehaviour
{
 GameObject[] eyes = new GameObject[2];
 string[] eyeAnchorNames ={ "LeftEyeAnchor", "RightEyeAnchor" };void Update()
 {
 for (int i = 0; i < 2; ++i)
 {
 //如果左右眼对象没有父物体,就不能用它
 if (eyes[i] != null && eyes[i].transform.parent != transform)
 {
 eyes[i] = null;
 }
// If we don't have an eye anchor, try to find one or create one
 if (eyes[i] == null)
 {
 Transform t = transform.Find(eyeAnchorNames[i]);
 if (t)
 eyes[i] = t.gameObject;
if (eyes[i] == null)
 {
 eyes[i] = new GameObject(eyeAnchorNames[i]);
 eyes[i].transform.parent = gameObject.transform;
 }
 }
// 更新眼睛位置
 eyes[i].transform.localPosition = InputTracking.GetLocalPosition((VRNode)i);
 eyes[i].transform.localRotation = InputTracking.GetLocalRotation((VRNode)i);
 }
 }
}

 

VR的图像效果

 

在VR项目中很多图像效果都是很耗费性能的相当于同样的场景渲染两次,因为每只眼睛都要渲染一次,用图像效果(image effects)越多对帧率影响越大.

由于VR是虚拟现实中用户眼睛看到的景象,所以一些图像效果在VR中一般是没有意义的,例如景深,模糊,镜头眩光等等.因为现实中人眼是看不到它们的.如果未来VR设备支持眼球跟踪,那么可以用景深效果提高真实感.

一些图像效果是可以用的,如抗锯齿(特别是低分辨率的VR眼镜),Color Grading(blogs.unity3d.com/2015/05/12/color-grading-with-unity-and-the-asset-store/)和Bloom在一些游戏中可以用的,可以试着用用它们调整出更好的效果.

Unity提供了很多图像效果供你使用(Assets > Import Package > Effects),在资源商店中也有很多不错的图像效果,如Colorful(https://www.assetstore.unity3d.com/en/#!/content/44845), Chromatica(https://www.assetstore.unity3d.com/en/#!/content/20743), Amplify Color(https://www.assetstore.unity3d.com/en/#!/content/20743), 其它等等(https://www.assetstore.unity3d.com/en/#!/search/page=1/sortby=popularity/query=category:148).

渲染比例

 

根据VR场景和使用的VR硬件,我们可能要改变渲染比例,控制镜头中图像与像素的比例.这意味着图像表现锐度会被改变.

这必须要通过代码,具体看这里: http://docs.unity3d.com/ScriptReference/VR.VRSettings-renderScale.html. 可以用下面这个脚本很容易的实现:

 

using UnityEngine;
using System.Collections;
using UnityEngine.VR;

namespace VRStandardAssets.Examples
{ 
 public class ExampleRenderScale : MonoBehaviour
 {
 [SerializeField] private float m_RenderScale = 1f; //这个渲染比,数值越高画质越好但是性能越低

void Start ()
 {
 VRSettings.renderScale = m_RenderScale;
 }
 }
}

可以在VR示例的Scenes/Examples/RenderScale中看到相关基本例子,它同样可以用在主菜单场景.

更改渲染比例的例子:Unity中默认渲染比是1.0:

5_renderscale-1x

如果我们增加到1.5,可以看到画面更清晰.

6_renderscale-1.5x

最后,我们降低渲染比例到0.5,我们会看到画面损失了:

7_renderscale-0.5x

根据实际运行测试,我们或降低渲染比例以提高性能,或提高渲染比例增加视觉清晰度.


原文:http://unity3d.com/learn/tutorials/topics/virtual-reality

由 四角钱 (XK) 翻译,转载请注明来自 http://blog.1vr.cn

Unity开发VR眼镜中文入门教程(1)

原文:http://unity3d.com/learn/tutorials/topics/virtual-reality

由 四角钱 (XK) 翻译,转载请注明来自 http://blog.1vr.cn


VR示例项目文件下载: https://www.assetstore.unity3d.com/en/#!/content/51519

Unity开发VR介绍

 

Unity对一些VR设备(docs.unity3d.com/ScriptReference/VR.VRDeviceType.html)做了内建支持,这篇教程将重点讲解Oculus眼镜.尤其是Oculus Rift Development Kit 2(简称DK2)和Gear VR消费者版(它需要三星Galaxy S6,S6 Edge, S6 Edge+,或Note 5).老版本的Gear VR支持S4,不过S4不会作为重点,但教程里会尽可能的让VR程序能在S4上运行以便有S4的开发者可以测试开发.

Unity同样支持其它一些VR头戴显示设备(简称HMDs),如HTC Vive,后期我们会更新这个教程讲解它的开发.

在Unity项目中开启VR支持

 

请确保安装了Unity5.3或更新的版本以及Oculus runtime 0.8,

我们到菜单Edit > Project Settings> Player > Other Settings > Rendering下:

 

1_enable_vr

然后勾选“Virtual Reality Supported”选择框.

2_enable_vr

 

 

在运行时,可以在代码中使用UnityEngine.VR.VRSettings.enabled(docs.unity3d.com/ScriptReference/VR.VRSettings-enabled.html)切换这个设置,代码如下:

 

using UnityEngine;
 using UnityEngine.VR;
 public class ToggleVR : MonoBehaviour
 {
 //VRSettings设置示例
 private void Update ()
 {
 //如果按下V键,则启用VRSettings.enabled VRSettings.enabled
 if (Input.GetKeyDown(KeyCode.V))
 {
 VRSettings.enabled = !VRSettings.enabled;
 Debug.Log("Changed VRSettings.enabled to:"+VRSettings.enabled);
 }
 }
 }

Unity中预览VR效果

当DK2与电脑连接好后,启用Unity编辑器的VR支持选项,进入播放模式就可以在DK2显示实际VR游戏画面,编辑器的游戏窗口也将正常显示VR游戏画面,可以随时预览随时修改VR游戏,比以往”左右双画面”的方式更好用.

3_enable_vr_cube

这里我们要注意,没必要为左右眼分别创建独立的相机,所有相机都会自动的以VR模式渲染,除了场景中用到Render Texture的相机.有关Render Texture更多信息可以查看手册.同样的Unity也会对VR模式下的相机机型渲染的优化,如虽然双眼有两个相机,但裁切和阴影渲染只运算一次.

关于VR的其它文档可以查看Unity使用手册(docs.unity3d.com/Manual/VROverview.html)及Unity脚本手册(docs.unity3d.com/ScriptReference/30_search.html?q=VR).

使用Unity开发VR游戏的软硬件建议

 

因为VR是一个非常新的媒介,在开发时会有些软硬件的限制:

硬件:

 

实现HMD中所需的帧率是很有必要的需求,这将带来很好的虚拟现实体验,比如在DK2中必须达到75fps,Gear VR必须达到60fps.如果帧率低于VR头盔最低需求,用户会有明显的感觉到,导致恶心,眩晕等.

运行VR程序的电脑显卡也要有能力输出VR眼镜需要的分辨率,如DK2是需要75hz下的1920×1080,如果你打算开发将来商业发布的Oculus Rift CV1,将要求你的电脑能输出2160×1200的分辨率.

如果你使用DK2,请确保你的电脑能支持VR硬件所需要的刷新率和分辨率,许多笔记本是独立与集成的双显卡,而这些显卡芯片通常不能输出75hz的1920×1080分辨率,请参阅Oculus文档(https://support.oculus.com/hc/en-us/articles/201835987-Oculus-Rift-Development-Kit-2-FAQ)中有关电脑硬件的推荐指南(https://www.oculus.com/en-us/oculus-ready-pcs/).

软件:

 

OS X: 现在我们可以用OSX 10.9+和Oculus 0.0.5 runtime来开发因为Oculus暂停了OS X的开发(https://www.oculus.com/en-us/blog/powering-the-rift/),所以我们推荐用Windows进行VR原生开发.

Windows: Windows 7, 8, 8.1和Windows 10都可以.

Android: 我们推荐Android OS Lollipop 5.1或更新版本..

显卡驱动: 请确保你的显卡驱动是最新版本,旧版本的显卡驱动可能不支持,如遇到不兼容的问题可打开Oculus Configuration Utility 查看显卡错误信息.

Oculus Runtime: 要在Unity5.3中启用VR支持,请使用Oculus Runtime 0.8或更高版本(https://developer.oculus.com/downloads/).

VR示例项目

 

我们在资源商店提供了一套VR示例项目.这套示例项目可以运行在DK2和Gear VR上,我们将关注Oculus及其它VR设备厂商的版本迭代并更新示例项目,请关注Unity博客.

可以从资源商店下载源文件:”https://www.assetstore.unity3d.com/#!/content/51519”.

示例场景

示例场景主要包括:

  • Intro: 介绍基本的使用
  • Menu: 通过菜单选择要玩的游戏
  • Flyer:一个屏幕飞行游戏
  • Maze: 一个桌面迷宫游戏.
  • Target Gallery:原地180°射击游戏
  • Target Arena: 原地360°射击游戏

另外也有一些场景:

  • InteractiveItem: 在VR中展示物体的基本方式
  • RenderScale: 如果使用渲染比例效果优化画质.
  • Reticle: 在VR中划线用准星引导的例子
  • Rotation: 显示一个能响应头部运动的物体.
  • Touchpad: 如何使用Gear VR的触控板.

涵盖了一下概念:

  • 俯瞰的桌游游戏风格
  • 沉浸的星际飞行风格
  • 第一视角射击风格
  • 原地360°防守射击风格
  • 在VR中使用Unity的UI
  • 空间中的UI界面
  • 在VR世界中对象触发基本框架,凝视物体等.
  • 基于准星的移动,缩放和在表面法线方向上绘制
  • 基于头部转动的运动
  • 使用Gear VR的触控板,包括单击,双击和滑动或者基于键盘和鼠标使用DK2.
  • 发布到Gear VR 和 DK2的条件
  • 当绕着一个点旋转相机时如何避免头晕恶心.
  • 相机淡出效果
  • 相机淡出切换位置效果
  • 对象池

虽然这个示例项目主要用来说明VR中的各种概念,并带你入门VR开发,但它也包括了一些很有用的例子给任何VR游戏开发人员使用:

  • 相机淡出效果
  • 相机淡出切换位置效果
  • VR中游戏对象交互框架
  • 保持动作以确认命令
  • 准星移动和缩放
  • 实现特定指向的UI箭头
  • 移动UI元素让它们始终面向相机
  • 与UI对象上色交互

需要Unity5.3.0下才能运行这些项目,并且硬件和软件满足上述的标准,有DK2(https://support.oculus.com/hc/en-us/articles/202741283-Get-Started-)(Oculus Runtime 0.8或更高(https://developer.oculus.com/downloads/))或含有兼容手机(www.samsung.com/global/galaxy/wearables/gear-vr/)的Gear VR(https://developer.oculus.com/documentation/mobilesdk/latest/)用于开发.

OCULUS UNITY 实例

 

根据你需要开发的功能,可以下载 Oculus Unity Utilities(https://developer.oculus.com/downloads/), 它包含了一些很有用的脚本和VR项目预设.如能够正确的改变瞳距(两眼之间的距离(https://developer.oculus.com/documentation/intro-vr/latest/concepts/bp_app_imaging/)),和可视化的渲染范围.

而我们这篇教程侧重于用Unity内建的VR支持,所以请到Oculus网站(https://developer.oculus.com/downloads/game-engines/0.1.3.0-beta/Oculus_Utilities_for_Unity_5/)查看哪种方式更适合开发你需求的VR项目.

你现在应该了解VR开发的软硬件需求以及如何在你项目中使用哪种技术实现VR功能.


 

原文:http://unity3d.com/learn/tutorials/topics/virtual-reality

由 四角钱 (XK) 翻译,转载请注明来自 http://blog.1vr.cn

 

Unity3d中制作Loading场景进度条所遇到的问题

背景

通常游戏的主场景包含的资源较多,这会导致加载场景的时间较长。为了避免这个问题,可以首先加载Loading场景,然后再通过Loading场景来加载主场景。因为Loading场景包含的资源较少,所以加载速度快。在加载主场景的时候一般会在Loading界面中显示一个进度条来告知玩家当前加载的进度。在Unity中可以通过调用Application.LoadLevelAsync函数来异步加载游戏场景,通过查询AsyncOperation.progress的值来得到场景加载的进度。

尝试——遇到问题

第一步当加载完Loading场景后,调用如下的LoadGame函数开始加载游戏场景,使用异步加载的方式加载场景1(Loading场景为0,主场景为1),通过Unity提供的Coroutine机制,我们可以方便的在每一帧结束后调用SetLoadingPercentage函数来更新界面中显示的进度条的数值。 继续阅读

四毛寻车记

原来住西直门, 是一楼, 车放在楼后方, 一个四轮无法进去的地方, 自己也装了监控, 平时就锁个无声的碟锁罩上车罩, 没任何问题. 去年十月假期因为这老小区要进行改造, 就搬到了大兴瀛海, 同样停在了楼下, 在汽车停车位的旁边, 还是只锁了无声碟锁, 也没用带警报的锁, 我怕有风之类的造成报警锁误触发扰民. 结果五天后的晚上三点多, 车上的防盗器报警呼叫我的手机, 当时睡的正香, 迷迷糊糊的起床隔窗往楼下摩托那看, 好像空了, 当时马上就精神了, 找手电筒再次往下看, 靠, 哈雷不见了!我马上喊我爱人说车丢了, 然后我打开电脑查车上的GPS轨迹, 由于没经历过这种事, 很慌乱, 加上新搬到那里, 路不熟, 看到行车轨迹也没马上判断出距离远近, 耽误了宝贵时间, 虽然随车的报警器被触发后唤醒有几分钟延迟, 但当时如果马上追出去, 加上路线熟悉, 应该可以追到盗窃者的. 让我爱人报警, 我穿衣下楼准备去追车, 这时候距离知道车被触动大约是过了五分多钟, 随车的GPS位置到了五环的旧忠桥并且提示设备电源断开了, 我和弟弟骑车到旧忠桥, 什么也没发现, 也没有找到拆掉的GPS防盗器.
GPS位置也停止在了旧忠桥上, 没有新的信息, 我们只有返回, 这时候片警已经来了, 看了车行驶本之类就去小区的监控室调阅监控, 因为知道准确的时间点所以很快找到了相关录像, 但是监控质量及角度等问题无法看到车具体被偷走的过程, 后来我通过分析还原了这个过程: 一辆遮挡号牌的金杯海狮车从小区北小门下来一人, 走到停车的位置确定车在无异常, 金杯车从西大门(门口栏杆晚上之间竖起, 门楼保安睡觉, 无人监管进出车辆)开进来直接停靠在摩托车边上并调头熄火, 然后至少三个人用了三分钟左右的时间将我的哈雷抬上金杯车开出小区. 车刚走不到一分钟就是我拿了手电筒往下照的时候. 去派出所做了个笔录, 片警说提交给刑警, 并说天亮后刑侦会来人勘查现场, 可第二天又说大兴区的规定, 摩托车无论价值都只由派出所侦查, 不能移交刑警, 刑侦的人也没有来, 说现场也没什么可采集的. 我便找他们和自己找关系查沿途监控, 结果是监控没启用及只是违章拍照探头, 没有全时录像. 加上感觉片警不尽责, 事实上他们就是什么也没干. 我就自己想办法找沿途监控和投诉. 折腾了几天后无任何新线索, 再过了将近一个月派出所才把案子立了, 给摩托车作价了七万五. 朋友土豆建议我把网上所有丢车信息全部清除, 现阶段只能等我的车再次出现了, 所以我进行了清理. 也想过买辆车, 套用丢的这套车手续, 毕竟购置税等等费用也要不少钱, 结果快年底的时候派出所那边象征性的做了回访说案子没有被遗忘, 他们因业务不熟后来才慢慢的把车上了盗抢网, 我也就放弃了套手续的想法, 京A摩托车牌照价格走势也算良好, 那时已经逼近八万了, 车虽然丢了, 但是牌照一年后能补回, 换算一下损失没有超过十万, 也算自我安慰了, 慢慢的梳理了情绪, 习惯了丢车的事实. 也经常关注各交易网试图发现车的踪迹, 无果. 继续阅读

Unity在 Web平台的未来

最近,我们收到很多开发者的咨询,大家最担心的问题就是网页游戏未来的发展,尤其是谷歌浏览器(Google Chrome)对Unity Web Player的支持,所以我们发表本文来帮助大家作出解答。

Google在2013年秋季宣布,计划在2014年年底,Chrome将停止对NPAPI的支持(http://blog.chromium.org/2013/09/saying-goodbye-to-our-old-friend-npapi.html)。NPAPI是可提供本地代码在Chrome中正常运行的API,也是Unity Web Player运行的基础。
继续阅读