【转载】Unity3D VR 教程:3.VR中的交互

原文地址:http://blog.csdn.net/sherlockchang/article/details/51336901

概述

VR开发中,我们经常需要激活一个用户正在盯着的物体。我们准备了一个示例,一个简单的可扩展的轻量级的系统,让用户和物体交互。这个系统由三个主要的脚本组成,VREyeRaycaster, VRInput, 和VRInteractiveItem - 下面有一些简短的说明和项目的源码。

VREyeRaycaster

这个脚本需要放在主摄像机上,每一次调用脚本的Update()向前发射一条射线, 调用Physics.Raycast来检测是不是击中了任何碰撞盒。这个功能可以设置为排除特定的layer(层),根据场景,可能需要把所有互动的物体移动到另一个层来做显示效果。

如果碰撞盒被射线集中,这个脚本会尝试在目标对象上查找VRInteractiveItem 控件:

[csharp] view plain copy

  1. VRInteractiveItem interactible = hit.collider.GetComponent<VRInteractiveItem>();    //attempt to get the VRInteractiveItem on the hit object

通过这个我们可以知道用户是否正在看着某个物体,或者停止查看某个物体,如果用户开始查看或者停止查看某个物体,我们可以做一些响应,例如调用某个方法。

VRInput

VRinput是个简单的类,它用来兼容动作发生的来源,是使用GearVR上触发的 swipes, taps, double-taps事件,还是使用DK2时,专为PC准备的输入事件。

可以在VRInput 中直接注册事件监听:

[csharp] view plain copy

  1. public event Action<SwipeDirection> OnSwipe;                // Called every frame passing in the swipe, including if there is no swipe.
  2. public event Action OnClick;                                // Called when Fire1 is released and it‘s not a double click.
  3. public event Action OnDown;                                 // Called when Fire1 is pressed.
  4. public event Action OnUp;                                   // Called when Fire1 is released.
  5. public event Action OnDoubleClick;                          // Called when a double click is detected.
  6. public event Action OnCancel;                               // Called when Cancel is pressed.

关于注册事件监听的更多信息,请查看我们的事件教程

VRInteractiveItem

任何想在VR中进行互动的物体都可以添加这个组件。需要物体上有碰撞盒。

这里有6个可以进行监听的事件:

[csharp] view plain copy

  1. public event Action OnOver;             // Called when the gaze moves over this object
  2. public event Action OnOut;              // Called when the gaze leaves this object
  3. public event Action OnClick;            // Called when click input is detected whilst the gaze is over this object.
  4. public event Action OnDoubleClick;      // Called when double click input is detected whilst the gaze is over this object.
  5. public event Action OnUp;               // Called when Fire1 is released whilst the gaze is over this object.
  6. public event Action OnDown;             // Called when Fire1 is pressed whilst the gaze is over this object.

添加一个boolean变量,用来查看现在是不是在Over( 悬停)的状态:

[csharp] view plain copy

  1. public bool IsOver
  2. {
  3. get{ return m_IsOver; }              // Is the gaze currently over this object?}

你可以创建自己的脚本来响应这些事件,这里有一个非常简单的例子,用到了这里的一些事件:

[csharp] view plain copy

  1. using UnityEngine;
  2. using VRStandardAssets.Utils;
  3. namespace VRStandardAssets.Examples
  4. {
  5. // This script is a simple example of how an interactive item can
  6. // be used to change things on gameobjects by handling events.
  7. public class ExampleInteractiveItem : MonoBehaviour
  8. {
  9. [SerializeField] private Material m_NormalMaterial;
  10. [SerializeField] private Material m_OverMaterial;
  11. [SerializeField] private Material m_ClickedMaterial;
  12. [SerializeField] private Material m_DoubleClickedMaterial;
  13. [SerializeField] private VRInteractiveItem m_InteractiveItem;
  14. [SerializeField] private Renderer m_Renderer;
  15. private void Awake ()
  16. {
  17. m_Renderer.material = m_NormalMaterial;
  18. }
  19. private void OnEnable()
  20. {
  21. m_InteractiveItem.OnOver += HandleOver;
  22. m_InteractiveItem.OnOut += HandleOut;
  23. m_InteractiveItem.OnClick += HandleClick;
  24. m_InteractiveItem.OnDoubleClick += HandleDoubleClick;
  25. }
  26. private void OnDisable()
  27. {
  28. m_InteractiveItem.OnOver -= HandleOver;
  29. m_InteractiveItem.OnOut -= HandleOut;
  30. m_InteractiveItem.OnClick -= HandleClick;
  31. m_InteractiveItem.OnDoubleClick -= HandleDoubleClick;
  32. }
  33. //Handle the Over event
  34. private void HandleOver()
  35. {
  36. Debug.Log("Show over state");
  37. m_Renderer.material = m_OverMaterial;
  38. }
  39. //Handle the Out event
  40. private void HandleOut()
  41. {
  42. Debug.Log("Show out state");
  43. m_Renderer.material = m_NormalMaterial;
  44. }
  45. //Handle the Click event
  46. private void HandleClick()
  47. {
  48. Debug.Log("Show click state");
  49. m_Renderer.material = m_ClickedMaterial;
  50. }
  51. //Handle the DoubleClick event
  52. private void HandleDoubleClick()
  53. {
  54. Debug.Log("Show double click");
  55. m_Renderer.material = m_DoubleClickedMaterial;
  56. }
  57. }
  58. }

要查看这个基础的示例的话,可以看一下VRSampleScenes/Scenes/Examples/ 中的InteractiveItem 场景

SelectionRadial(环形选择区) 和 SelectionSlider(滑块选择区)

(用来确认选项)

我们用了一个圆形选择区,还有一个滑块选择区,玩家可以按住Fire1 来确认交互动作:

按住输入的按键, 选择条会填满, 然后发送OnSelectionComplete (选择完成)或者 OnBarFilled(读条失败)事件。这部分代码在SelectionRadial.cs和SelectionSlider.cs 文件中并且有详细的注释。对于VR来说,站在用户体验角度考虑,用户知道他们在做什么而且能够随时把控整个各个方面。同时提供一个“held input (保持输入)”的确认模式,作为对立即响应事件的一些妥协。

VR示例场景中的一些互动示例

现在我们来研究一下VR示例项目中的一些例子。我们会讨论一下每个场景的互动效果和它们的实现方法。

在菜单场景中的互动

每个菜单画面都有几个组件。特别需要了解一下的是MenuButton, VRInteractiveItem, 和Mesh Collider。

MenuButton 组件监听了来自 VRInteractiveItem 组件的 OnOver 和 OnOut 事件, 当准星悬停在菜单画面上的时候, 环形选择块就会出现, 当视线离开menu item(菜单选项)时, 这个环形选择块会消失。当选择圈可见的时候,按下Fire1 键, 这个环形会逐渐填满:

这个类也监听了OnSelectionComplete 事件, 当环形圈填满的时候,HandleSelectionComplete 方法会被调用,它会让显示器淡出然后读取所选择的关卡。

[csharp] view plain copy

  1. private void OnEnable ()
  2. {
  3. m_InteractiveItem.OnOver += HandleOver;
  4. m_InteractiveItem.OnOut += HandleOut;
  5. m_SelectionRadial.OnSelectionComplete += HandleSelectionComplete;
  6. }
  7. private void OnDisable ()
  8. {
  9. m_InteractiveItem.OnOver -= HandleOver;
  10. m_InteractiveItem.OnOut -= HandleOut;
  11. m_SelectionRadial.OnSelectionComplete -= HandleSelectionComplete;
  12. }
  13. private void HandleOver()
  14. {
  15. // When the user looks at the rendering of the scene, show the radial.
  16. m_SelectionRadial.Show();
  17. m_GazeOver = true;
  18. }
  19. private void HandleOut()
  20. {
  21. // When the user looks away from the rendering of the scene, hide the radial.
  22. m_SelectionRadial.Hide();
  23. m_GazeOver = false;
  24. }
  25. private void HandleSelectionComplete()
  26. {
  27. // If the user is looking at the rendering of the scene when the radial‘s selection finishes, activate the button.
  28. if(m_GazeOver)
  29. StartCoroutine (ActivateButton());
  30. }
  31. private IEnumerator ActivateButton()
  32. {
  33. // If the camera is already fading, ignore.
  34. if (m_CameraFade.IsFading)
  35. yield break;
  36. // If anything is subscribed to the OnButtonSelected event, call it.
  37. if (OnButtonSelected != null)
  38. OnButtonSelected(this);
  39. // Wait for the camera to fade out.
  40. yield return StartCoroutine(m_CameraFade.BeginFadeOut(true));
  41. // Load the level.
  42. SceneManager.LoadScene(m_SceneToLoad, LoadSceneMode.Single);
  43. }

这里有一些关于Selection Radial的示例, 注意截图中央的粉色图形。

只有点状准星的:

空的选择确认圈, 因为现在正在看着menu 场景所以出现:

选择确认圈正在填充(用户正在看着菜单画面, 而且按住了 输入设备的 Fire1 键):

通过在研究示例项目中的进度条和环形试,着掌握这个模式。我们建议你在自己的VR项目上考虑一下这个方法,这样能保证用户体验的一致性,也能帮助他们适应这个新的设备。

Maze Scene 中的交互

迷宫游戏提供了一个桌游模式的交互,在这里你需要用开关(挡板)来引导角色必考炮塔,到达终点。

为角色选择目的地的时候,会出现一个目的地标记,路上会出现一条路线,让角色沿着轨迹前进。在触控板上滑动,或者按下方向键,或者用手柄左摇杆,可以旋转画面。

MazeFloor 对象 有一个MeshCollider 组件和一个VRInteractiveItem 组件, 让它能在VR中进行交互:

MazeCourse 物体 包含有MazeFloor 和MazeWalls ,包含着用作迷宫布局的几何体:

MazeCourse 物体添加了MazeTargetSetting脚本, 有一个VRInteractiveItem 的引用,指向MazeFloor物体上的VRInteractiveItem 组件:

MazeTargetSetting 监听了来自VRInteractiveItem 的 OnDoubleClick 事件, 然后它会发送OnTargetSet 事件。这个事件会把准星的Transform(空间坐标信息)当作变量一起传出:

[csharp] view plain copy

  1. public event Action<Transform> OnTargetSet;                     // This is triggered when a destination is set.
  2. private void OnEnable()
  3. {
  4. m_InteractiveItem.OnDoubleClick += HandleDoubleClick;
  5. }
  6. private void OnDisable()
  7. {
  8. m_InteractiveItem.OnDoubleClick -= HandleDoubleClick;
  9. }
  10. private void HandleDoubleClick()
  11. {
  12. // If target setting is active and there are subscribers to OnTargetSet, call it.
  13. if (m_Active && OnTargetSet != null)
  14. OnTargetSet (m_Reticle.ReticleTransform);
  15. }

MazeCharacter 物体上的 Player 组件和 MazeDestinationMarkerGUI 物体上的 DestinationMarker 组件都监听了OnTargetSet这个事件,然后相应的做出了反应。

角色使用了Nav Mesh systems(导航系统)在迷宫中寻路。Player 组件实现了HandleSetTarget方法,在方法中,把导航系统的目标点设置为准星的坐标, 然后更新它对玩家轨迹的渲染:

[csharp] view plain copy

  1. private void HandleSetTarget(Transform target)
  2. {
  3. // If the game isn‘t over set the destination of the AI controlling the character and the trail showing its path.
  4. if (m_IsGameOver)
  5. return;
  6. m_AiCharacter.SetTarget(target.position);
  7. m_AgentTrail.SetDestination();
  8. }

DestinationMarker (目标点生成器)会把标记移动到准星Transform的位置:

[csharp] view plain copy

  1. private void HandleTargetSet(Transform target)
  2. {
  3. // When the target is set show the marker.
  4. Show();
  5. // Set the marker‘s position to the target position.
  6. transform.position = target.position;
  7. // Play the audio.
  8. m_MarkerMoveAudio.Play();
  9. // Play the animation on whichever layer it is on, with no time offset.
  10. m_Animator.Play(m_HashMazeNavMarkerAnimState, -1, 0.0f);
  11. }

你可以看到准星,目的地制作器,玩家,和轨迹:

迷宫中的开关也是一个在VR中和物体互动的例子。使用了一个Collider(碰撞盒),像VRInteractiveItem 和SelectionSlider 这两个类一样。

像以上演示的和其他物体的互动, SelectionSlider脚本监听了 VRInteractiveItem 和 VRInput 发出的事件:

[csharp] view plain copy

  1. private void OnEnable ()
  2. {
  3. m_VRInput.OnDown += HandleDown;
  4. m_VRInput.OnUp += HandleUp;
  5. m_InteractiveItem.OnOver += HandleOver;
  6. m_InteractiveItem.OnOut += HandleOut;
  7. }

Flayer 场景中的交互

飞行器场景是一个无限飞行的游戏,玩家需要控制飞船在场景中飞行,使用Fire1 进行射击, 射击小行星,穿过空中的门,都能增加分数。玩法类似飞行俱乐部和星际火狐。

在交互方面,Flyer是一个更简单的案例, FlyerLaserController 监听了 VRInput 的O nDown 事件来发射激光:

[csharp] view plain copy

  1. private void OnEnable()
  2. {
  3. m_VRInput.OnDown += HandleDown;
  4. }
  5. private void HandleDown()
  6. {
  7. // If the game isn‘t running return.
  8. if (!m_GameController.IsGameRunning)
  9. return;
  10. // Fire laser from each position.
  11. SpawnLaser(m_LaserSpawnPosLeft);
  12. SpawnLaser(m_LaserSpawnPosRight);
  13. }

Shooter180 和 Shooter360 场景中的交互(Target Gallery/Target Arena)

VR示例实现了两个射击游戏,180度走廊打靶射击游戏,和360度的竞技场射击游戏。

每个在射击游戏里创建的靶子都有 Collider, VRInteractiveItem 和 ShootingTarget 组件。

ShootingTarget 组件监听了VRInteractiveItem发出的OnDown事件,来判断标靶是不是被射击。这个方法适合即时射击,如果要做一个击中数的模式,我们需要另一个方案实现。

现在你可能对 VR交互组件 有了一个大概认识,知道了这些组件是如何在VR 示例项目中使用的。现在我们来讨论一下注视和准星是如何在我们的VR示例中生效的。

注视

在VR中侦测玩家正在查看的方向是很重要的,关系到是否允许用户和物体互动,激活动画,或者对对目标发射子弹等等。我们引用的这个动作,在VR中叫做“gaze”(注视), 而且,接下来我们会在我们的VR文章中,使用这个术语。

由于大多数头戴式显示设备还不支持眼球追踪,我们现在只能估算玩家的注视。因为镜片的扭曲,这意味着玩家基本上是朝前看的,所以有一个简单的解决方案。就像在概述中提到的,我们只需要在摄像机中心朝前发射一条射线,然后查找这条射线所有碰撞的物体。当然,这意味着任何物体能被碰撞(或者通过注视进行互动)的物体都要有碰撞盒。

准星

准星可以帮助指示出玩家的视野中心。准星可以是一个简单的点,或者是个交叉十字线,这要看项目的需求。

在传统的3D游戏中,准星通常被设置为空间中固定的点, 通常是屏幕的中心。 在VR中定位一个准星要更复杂:用户在VR场景中观察环境,视线会聚集到离摄像机比较近的物体上。如果准星有一个固定的位置, 用户会看到两个:可以把手指放在眼前然后看远处的物体来模拟一下这个感觉, 如果你聚焦到你的手指,背景的物体看起来会变成两个, 反之同样。这被叫做voluntary Diplopia(自发性复视)。

要避免用户观察环境时和注视不同距离的物体时看到两个准星,需要把准星放到物体表面正在被观察的点,然后根据摄像机到这个点的距离对它进行缩放。

有一些简单的例子来演示准星如何处理不同距离和尺寸, 来自 Examples/Reticlescene (示例/准星场景)

准星被放置在一个物体上,靠近摄像机:

准星被放置在一个远处的物体上:

准星放置在远处的位置:

由于调整了位置和缩放, 准星在用户看来是一样的大小,也忽略的它到摄像机的距离。

当注视的射线上没有物体的时候,我们简单的把准星放到一个预设的距离上。在一个护腕环境,这个被简单的放在摄像机的最远端裁剪面上,或者在室内场景的话,这个位置会变得更近。

越过其他物体渲染准星

如果准星被放置在了和物体同样的位置, 这个准星可能和其他附近的物体有重叠:

要解决这个问题,我们需要保证准星渲染在所有其他物体之上。VR示例中提供了一个基于 “UI/Unlit/Text”的shader,叫做UIOverlay.shader。给材质选择shader的时候,可以在“UI/Overlay”下面找到它。

这个shader可以用在UI元素和文字,会在其它物体的最上方渲染:

调整准星到场景中的其他物体

最后,如果需要旋转准星来贴合到视线击中的物体上。我们可以用RaycastHit.normal。这里演示如何在准星中设置:

[csharp] view plain copy

  1. public void SetPosition (RaycastHit hit)
  2. {
  3. m_ReticleTransform.position = hit.point;
  4. m_ReticleTransform.localScale = m_OriginalScale * hit.distance;
  5. // If the reticle should use the normal of what has been hit...
  6. if (m_UseNormal)
  7. // ... set it‘s rotation based on it‘s forward vector facing along the normal.
  8. m_ReticleTransform.rotation = Quaternion.FromToRotation (Vector3.forward, hit.normal);
  9. else
  10. // However if it isn‘t using the normal then it‘s local rotation should be as it was originally.
  11. m_ReticleTransform.localRotation = m_OriginalRotation;
  12. }

可以在迷宫场景中看到这个动作。

下面是准星如何贴合到墙壁上:

准星贴合到地面:

我们已经引入了一个示例准星脚本。 和 VREyeRaycaster 一起把准星定位到场景中,有选项控制是否贴合到目标物体表面。

以上所有都能在VRSampleScenes/Scenes/Examples/ 文件夹下的 Reticle scene 查看。

VR中头部的旋转和坐标

HMD(头戴式显示设备)旋转和坐标的明显的用途是用来观察环境,但是这两个变量,用来和环境互动也是可以的。

需要使用 VR.InputTracking class 这个类来得到这两个值,然后区分需要进入哪个 VRNode(VR节点)。我们需要使用VRNode.Head来得到头部的旋转。头部,而不是每只眼睛。关于这个的更多信息,可以参考Getting Started with VR Development这篇文章。

把旋转作为一种输入类型的示例,基于头部旋转来精确的旋转一个菜单或者其他物体。可以在这里找到这里示例,VRSampleScenes/Examples/Rotation scene, 以下示例脚本:

[csharp] view plain copy

  1. // Store the Euler rotation of the gameobject.
  2. var eulerRotation = transform.rotation.eulerAngles;
  3. // Set the rotation to be the same as the user‘s in the y axis.
  4. eulerRotation.x = 0;
  5. eulerRotation.z = 0;
  6. eulerRotation.y = InputTracking.GetLocalRotation(VRNode.Head).eulerAngles.y;

可以看到物体会根据玩家查看的方向进行旋转:

在我们的示例Flyer game(飞行器游戏)中,你可以看到FlyerMovementController中,基于头部的旋转调整飞船坐标:

[csharp] view plain copy

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

VR 游戏中 与触控板和键盘的交互

Gear VR 在设备侧面有触控板。对于Unity来说,表现为出镖, 可以通过下面的方式调用:

Input.mousePosition

Input.GetMouseButtonDown

Input.GetMouseButtonUp

使用Gear VR时,可能也许需要获取触控板的滑动数据。我们引入了一个VRInput 脚本来处理滑动,触屏点击,和触屏双击。也接受键盘输入中的方向键和左Ctrl键(Unity默认输入术语中的Fire1),来触发swipes(滑动)和taps(点击)。

在Unity编辑器中,由于现在没有办法测试Unity到GearVR的内容,可能用DK2来测试GearVR 的内容。由于Gear VR 触控板事件是作为鼠标事件运作的,我们可以简单的使用鼠标来模拟输入。由于使用HMD(头戴式显示设备)时,定位键盘要更简单一点, 为了方便,VRInput也会接受方向键作为滑动事件,然后左Ctrl(Fire1)作为触屏点击事件(taps)。

对于手柄的基础操作,左摇杆的动作会作为华东,然后按下其中一个按钮会作为点击。

在VRSampleScenes/Scenes/Examples/Touchpad中有一个例子监听了swipes(滑动)事件。

一下是ExampleTouchpad 脚本, 按照滑动的方向,对刚体添加扭力,让物体能够旋转起来。

[csharp] view plain copy

  1. using UnityEngine;
  2. using VRStandardAssets.Utils;
  3. namespace VRStandardAssets.Examples
  4. {
  5. // This script shows a simple example of how
  6. // swipe controls can be handled.
  7. public class ExampleTouchpad : MonoBehaviour
  8. {
  9. [SerializeField] private float m_Torque = 10f;
  10. [SerializeField] private VRInput m_VRInput;
  11. [SerializeField] private Rigidbody m_Rigidbody;
  12. private void OnEnable()
  13. {
  14. m_VRInput.OnSwipe += HandleSwipe;
  15. }
  16. private void OnDisable()
  17. {
  18. m_VRInput.OnSwipe -= HandleSwipe;
  19. }
  20. //Handle the swipe events by applying AddTorque to the Ridigbody
  21. private void HandleSwipe(VRInput.SwipeDirection swipeDirection)
  22. {
  23. switch (swipeDirection)
  24. {
  25. case VRInput.SwipeDirection.NONE:
  26. break;
  27. case VRInput.SwipeDirection.UP:
  28. m_Rigidbody.AddTorque(Vector3.right * m_Torque);
  29. break;
  30. case VRInput.SwipeDirection.DOWN:
  31. m_Rigidbody.AddTorque(-Vector3.right * m_Torque);
  32. break;
  33. case VRInput.SwipeDirection.LEFT:
  34. m_Rigidbody.AddTorque(Vector3.up * m_Torque);
  35. break;
  36. case VRInput.SwipeDirection.RIGHT:
  37. m_Rigidbody.AddTorque(-Vector3.up * m_Torque);
  38. break;
  39. }
  40. }
  41. }
  42. }

VR示例中的VRInput例子

像上文提到的,所有我们的示例游戏,都用VRInput来处理触控板和鼠标事件。在Maze(迷宫)中的摄像机也响应了滑动事件。

Maze(迷宫)

在这个场景中,摄像机轨道监听了swipes(滑动)事件,能够改变视角:

[csharp] view plain copy

  1. private void OnEnable ()
  2. {
  3. m_VrInput.OnSwipe += HandleSwipe;
  4. }
  5. private void HandleSwipe(VRInput.SwipeDirection swipeDirection)
  6. {
  7. // If the game isn‘t playing or the camera is fading, return and don‘t handle the swipe.
  8. if (!m_MazeGameController.Playing)
  9. return;
  10. if (m_CameraFade.IsFading)
  11. return;
  12. // Otherwise start rotating the camera with either a positive or negative increment.
  13. switch (swipeDirection)
  14. {
  15. case VRInput.SwipeDirection.LEFT:
  16. StartCoroutine(RotateCamera(m_RotationIncrement));
  17. break;
  18. case VRInput.SwipeDirection.RIGHT:
  19. StartCoroutine(RotateCamera(-m_RotationIncrement));
  20. break;
  21. }
  22. }

关于为什么场景的摄像机轨道而不是直接旋转这个迷宫本身,请查看 Movement article 这篇文章。

现在你对VR 示例场景中,基础VR交互的工作原理有了一个更好的认识。有很多方法去完成这个事情,但是这个方法学起来又快又简单。在下一篇文章里,我们会讨论VR中不同类型的用户界面。同时记得,打算向同样研究VR的朋友们提问关于VR的问题的话,你可以跳转到Unity官方论坛VR板块

在迷宫场景中看到这个动作。

下面是准星如何贴合到墙壁上:

时间: 2024-10-12 01:12:10

【转载】Unity3D VR 教程:3.VR中的交互的相关文章

NVisionXR_iOS教程六 —— 场景中对象交互

本章节将介绍如何与场景中的对象进行交互,接着上一章节的代码,我们往立方体对象 添加如下代码,并实现它的代理<HitEventDelegate>  代码:     // 创建一个立方体      NVBoxWidget *cube = [[NVBoxWidget alloc] initWithScenePlay:self WidgetName:@"cube"];      // 添加材质,传入的是对应的material 材质名      [cube setAppearance

Unity5.3官方VR教程重磅登场-系列7 优化VR体验

本文转自:知乎专栏-笨猫快乐学编程,作者:王寒 简介 对于VR应用来说,如果想要让用户获得好的用户体验,特别是免除恶心眩晕的困扰,在VR开发中进行优化是必不可少的,惟其如此才能达到我们期望的游戏运行帧速.和其它平台上的开发不同,对VR应用的优化应该在项目启动的前期就开始,而且应该贯穿始终,而不是像传统项目那样把优化的工作留到最后去做.此外,在目标设备上进行实际测试也是非常有必要的. 相比非VR项目来说,VR项目是非常消耗计算资源的,其主要原因就是所有的画面都必须为每只眼睛单独渲染一次.因此,在开

Daydream VR入门基础教程,VR开发基础知识——VR view基本介绍

VR view基本介绍 VR view是Google在2016年4月推出的一个VR基本概念,是一种"客户端"VR显示技术,可将 360 度照片或视频部署在各种设备上的简易方式,囊括 PC 端和移动端.在APP上嵌入VR View代码之后,全景照片或者视频将会变成分屏的VR内容.用户可以在手机上通过Cardboard等盒子或者在PC端通过头盔体验VR. 我们来看看一张VR全景图片是什么样的: 为什么是两张一模一样的呢?因为这是分别给左右眼观看的,遵循了VR view视图的基本规则,关于V

【Unity3D基础教程】给初学者看的Unity教程(三):通过制作Flappy Bird了解Native 2D中的Sprite,Animation

作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 上一次我们讲了MonoBehaviour的前世今生,了解了游戏中的每一个GameObjec都是由脚本控制的,这一次我们开始将Unity中Native 2D中的Sprite,并且使用Animation来让Sprite动起来. 在接下来的几篇博客里,我会通过做一个Flappy Bird来讲解Unity中各个组件的使用,项目的源代码在这里:U

【Unity3D基础教程】给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D

作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 在第一篇文章[Unity3D基础教程]给初学者看的Unity教程(一):GameObject,Compoent,Time,Input,Physics我已经讲过了一些关于刚体和碰撞的关系,这次我们就通过Flappy Bird这个事例来讲解一下刚体和碰撞体在游戏中的具体应用.相关代码可以参考Flappy Bird的源码. 认识RigidBo

GOOGLE VR SDK开发VR游戏,VR播放器之中的一个

近期一年来,VR虚拟现实和AR增强现实技术的宣传甚嚣尘上.事实上VR,AR技术非常早就有了,一直没有流行开来.不可否认价格是影响技术推广的最大壁垒. 谷歌对VR最大的贡献是提供了便宜的谷歌眼镜,依照GOOGLE提供的图纸,使用两个放大镜和一个披萨盒就能轻松DIY出自己的VR眼镜,同一时期谷歌推出来开源的VR SDK,使得开发人员能够轻松构建VR游戏和VR播放器,使得差点儿全部对这一切感兴趣的公司能够轻松的低成本的在技术上布局VR产业链. 非常多VR眼镜已经降到了几十块钱.毫无疑问,谷歌又借着便宜

【Unity3D基础教程】给初学者看的Unity教程(二):所有脚本组件的基类 -- MonoBehaviour的前世今生

作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 上一次我们讲了GameObject,Compoent,Time,Input,Physics,其中Time,Input,Physics都是Unity中的全局变量.GameObject是游戏中的基本物件.GameObject是由Component组合而成的,GameObject本身必须有Transform的Component,这也加深了我们

【Unity3D基础教程】给初学者看的Unity教程(零):如何学习Unity3D

[Unity3D基础教程]给初学者看的Unity教程(零):如何学习Unity3D http://www.cnblogs.com/neverdie/p/How_To_Learn_Unity3D.html 作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! Unity3D有什么优势 Unity3D是一个跨平台的游戏引擎,如果您开始看这篇博客的话,你一定实在权衡学习或者使用哪种游戏引擎来开发您的游戏,

【Unity3D技巧】在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信

作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 在前面两篇文章: [Unity3D基础教程]给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D [Unity3D基础教程]给初学者看的Unity教程(三):通过制作Flappy Bird了解Native 2D中的Sprite,Animation 我们了解