开发
开发
选择平台

开始构建首个 VR 应用

本教程将帮助您在 Unity 构建首个 VR 应用。这是一个基础应用,它介绍了主要的 Unity 概念,例如 3D 对象、组件和构建设置。本教程的目标不是教您使用 Oculus 集成项目包,而是引导您了解 Unity 的基本概念和界面。本教程结束时,您将构建出一个可以在电脑上运行的 VR 应用。

这个应用是关于什么的?

这是一个简单的游戏!这个场景包含一个被四面墙包围的游戏区和一个充当玩家角色的球。游戏的目的就是让球一直滚动,但不能撞到墙。如果球撞上了任意一面墙,墙面的颜色会发生变化,屏幕上会显示文字,表示球撞到了墙。为了输入,您需要使用键盘或 Unity 兼容的摇杆。
以下是我们将构建的应用:

视频:球运动和撞墙行为演示。

前提条件

在开始本教程之前,请确保您已设置好开发环境,并执行了必要的设置。
  1. 安装 Unity,并按照设置 Unity 以进行 VR 开发创建新项目。
  2. 完成设置头戴设备以进行开发和指南相关操作。
  3. 配置构建设置

基本概念

本节介绍了创建应用或游戏机制的基本要素。我们只解释核心工作流程概念,这些概念在构建此 VR 应用时很实用。如需详细了解 Unity 的概念和工作流程,请前往 Unity 用户手册
  • 场景是容纳各种游戏对象的容器。
  • 游戏对象是代表角色、道具、灯光、相机或特效的基本对象。在此应用中,我们将使用由原始形状构成的 3D 对象,如平面、立方体和球体。
  • 组件定义游戏对象的行为。变换组件主要决定每个游戏对象的位置、旋转角度和大小,这些值以每个属性的 X、Y 和 Z 坐标表示。默认情况下,位置设为 (0,0,0),这也被称为场景中所有坐标计算的原点。
  • 材质为任何对象添加纹理和颜色。在此应用中,我们只会使用材质来为对象上色,而不会涉及其他技术细节。

构建

第 1 步:创建材质,为游戏对象上色。
任何应用设计的基本需求之一就是添加颜色和纹理。您可以使用材质来定义各种外观效果,例如颜色、着色器、纹理等。在此应用中,我们只会使用材质来上色。
  1. Project(项目)视图中,在 Assets(素材)文件夹中,创建新文件夹,用来存储应用中不同游戏对象的材质,将其重命名为 Materials(材质),然后双击打开文件夹。
  2. 在菜单中,前往 Assets(素材)> Create(创建)> Material(材质),并将该材质重命名为 floor-color(地面颜色)。
  3. Inspector(检查器)视图的 Main Maps(主地图)下,点击 Albedo 色域以打开颜色选择器,更改所选择的颜色。在此应用中,我们将使用 RGB 值 (3,32,70)。
  4. 重复第 2 步至第 4 步,为墙壁、玩家球和碰撞时墙壁的颜色变化创建材质。将这些材质重命名为 wall-color(墙壁颜色)、ball-color(球颜色)和 after-collision(碰撞后),将 RGB 值分别设为 (255,255,255)、(240,240,0) 和 (241,107,8)。
第 2 步:构建地面、玩家球和四面墙。
此应用的游戏对象为地面、球和四面墙,我们将使用库存的 Unity 平面、球体和立方体来构建它们。
地面
  1. 在菜单中,前往 GameObject > 3D Object(3D 对象)> Plane(平面)。
  2. Hierarchy(层级结构)视图中,将其重命名为 floor(地面)。
  3. Inspector(检查器)视图的 Transform(变换)下,验证位置是否设为原点,即 (0,0,0)。如果没有,请重置为 (0,0,0)。
  4. Transform(变换)下,将大小设为 (2,1,2) 以放大地面。平面对象是平坦的,没有任何体积。因此,Y 值默认设为 1。
  5. 地面颜色材质拖放到平面上以上色。
玩家球
  1. 在菜单中,前往 GameObjec > 3D Object(3D 对象)> Sphere(球体)。
  2. Hierarchy(层级结构)视图中,将其重命名为 player-ball(玩家球)。
  3. Materials(材质)文件夹中,将球颜色拖放到球体上。
  4. Inspector(检查器)视图的 Transform(变换)下,确保位置设为 (0,0,0),并将 Y 值设为 0.5,让球停在地面上,即 (0,0.5,0)。
四面墙
  1. 在菜单中,前往 GameObject > 3D Object(3D 对象)> Cube(立方体)。
  2. Materials(材质)文件夹中,将墙壁颜色拖放到立方体上。
  3. Inspector(检查器)视图的 Transform(变换)下,将位置重置为 (0,0,0),并将大小设为 (0.5,2,20.5),拉伸墙壁,让墙壁对齐地面边缘。
  4. Hierarchy(层级结构)视图中,右键点击立方体,执行以下操作:
    a.将立方体重命名为 first-wall(第一面墙)。
    b.将立方体复制三次,再添加三面墙,将每面墙分别重命名为 second-wall(第二面墙)、third-wall(第三面墙)和 fourth-wall(第四面墙)。
  5. Hierarchy(层级结构)视图中,选择 third-wall(第三面墙)。然后在 Inspector(检查器)视图的 Transform(变换)下,将旋转角度设为 (0,90,0)。对第四面墙重复此步骤。
  6. Hierarchy(层级结构)视图中,选择 first-wall(第一面墙)。然后在 Inspector(检查器)视图的 Transform(变换)下,输入以下值以重新定位墙壁,使墙壁从各个方向包围地面。对剩余墙壁重复此步骤。
    第一面墙设为 (-10,0,0)
    第二面墙设为 (10,0,0)
    第三面墙设为 (0,0,10)
    第四面墙设为 (0,0,-10)
第 3 步:调整相机和光线。
调整主相机和光线,以获得更好的场景视图。
  1. Hierarchy(层级结构)视图中,选择 Main Camera(主相机)。
  2. Inspector(检查器)视图的 Transform(变换)下,将位置设为 (0,10,-20),将旋转角度设为 (20,0,0)。
  3. Hierarchy(层级结构)视图中,选择 Directional Light(平行光)。
  4. Inspector(检查)视图的 Transform(变换)下,将旋转角度设为 (50,60,0)。
第 4 步:为玩家球添加动作。
  1. Hierarchy(层级结构)视图中,选择 player-ball(玩家球)。
  2. Inspector(检查器)视图中,执行以下操作:
    a.点击 Add Component(添加组件)> Physics(物理属性)> Rigidbody(刚体)。
    b.点击 Add Component(添加组件)> New Script(新脚本),将其命名为 PlayerController,然后点击 Create and Add(创建并添加)。
    c.点击 PlayerController 脚本旁边的齿轮图标,然后点击 Edit Script(编辑脚本),在代码编辑器中打开脚本。
    d.用键盘输入以下代码,以替换示例代码,并增加力度来移动球。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // Appears in the Inspector view from where you can set the speed
    public float speed;

    // Rigidbody variable to hold the player ball's rigidbody instance
    private Rigidbody rb;

    // Called before the first frame update
    void Start()
    {
        // Assigns the player ball's rigidbody instance to the variable
        rb = GetComponent<Rigidbody>();
    }

    // Called once per frame
    private void Update()
    {
        // The float variables, moveHorizontal and moveVertical, holds the value of the virtual axes, X and Z.

        // It records input from the keyboard.
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        // Vector3 variable, movement, holds 3D positions of the player ball in form of X, Y, and Z axes in the space.
        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

        // Adds force to the player ball to move around.
        rb.AddForce(movement * speed * Time.deltaTime);
    }
}
  1. Inspector(检查器)视图的 PlayerController 脚本下,找到 Speed(速度),输入速度值。例如,500。此变量与我们在第 4.2.d 步中在 PlayerController 脚本中声明的速度变量相同。
  2. 点击顶部的“Play”(播放)按钮,预览您的应用。按下键盘上的箭头键,让球四处滚动。
第 5 步:添加文本。
  1. 在菜单上,前往 Game Object(游戏对象)> UI(用户界面)> Text(文本)。
  2. Hierarchy(层级结构)视图中,选择 Text(文本),将其重命名为 message(消息)。
  3. Scene(场景)视图选项卡切换到 Game(游戏)视图选项卡,预览文本在玩家上的显示效果。
  4. Inspector(检查器)视图的 Rect Transform(矩形变换)下,调整文本的位置。如有需要,您也可以更改字体颜色和字体大小。
第 6 步:当球撞上墙壁或结束碰撞时,更改墙壁颜色并显示文本。
球碰到墙壁时即发生碰撞。您可以添加特效来突显碰撞。例如,球撞上墙壁时,墙壁颜色改变,屏幕上显示文本“Ouch!(哎哟!)”。而当球重新开始滚动时,墙壁变回原来的颜色,屏幕上显示文本“Keep Rolling...(继续滚动……)”。
  1. Hierarchy(层级结构)中,选择 first-wall(第一面墙)。
  2. Inspector(检查器)视图中,点击 Add Component(添加组件)> New Script(新脚本),将其命名为 ColorController,然后点击 Create and Add(创建并添加)。
  3. 点击 ColorController 脚本旁边的齿轮图标,然后点击 Edit Script(编辑脚本),在代码编辑器中打开脚本。
  4. 用以下代码替换示例代码。
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    public class ColorController : MonoBehaviour
    {
     public Material[] wallMaterial;
     Renderer rend;
    
     // Appears in the Inspector view from where you can assign the textbox
     public Text displayText;
     // Start is called before the first frame update
     void Start()
     {
         // Assigns the component's renderer instance
         rend = GetComponent<Renderer>();
         rend.enabled = true;
         displayText.text = "";
     }
     // Called when the ball collides with the wall
     private void OnCollisionEnter(Collision col)
     {
         // Checks if the player ball has collided with the wall.
         if (col.gameObject.name == "player-ball")
         {
             displayText.text = "Ouch!";
             rend.sharedMaterial = wallMaterial[0];
         }
     }
     // It is called when the ball moves away from the wall
     private void OnCollisionExit(Collision col)
     {
         if (col.gameObject.name == "player-ball")
         {
             rend.sharedMaterial = wallMaterial[1];
             displayText.text = "Keep Rolling...";
         }
     }
    }
    
  5. Hierarchy(层级结构)视图中,选择 first-wall(第一面墙)。
  6. Inspector(检查器)视图的 ColorController 脚本下,执行以下操作:
    a.展开 Wall Material(墙壁材质),在 Size(尺寸)中,输入 2,然后分别将 after-collision(碰撞后)和 wall-color(墙壁颜色)拖放到 Element 0(元素 0)和 Element 1(元素 1)中。
    b.点击 Display Text(显示文本)旁边的齿轮图标,选择 message(消息)。Display Text(显示文本)字段与我们在第 6.4 步中在 ColorController.cs 脚本中声明的字段相同。
  7. Hierarchy(层级结构)视图中,选择 second-wall(第二面墙)。
  8. Inspector(检查器)视图中,点击 Add Components(添加组件)> Scripts(脚本),从列表中选择 ColorController,然后重复第 6 步。
  9. 对剩余墙壁重复第 7 步和第 8 步。
  10. 点击顶部的“Play”(播放)按钮,预览您的应用。按下键盘上的箭头键,让球四处滚动。
第 7 步:构建并运行应用。
根据您在构建设置中选择的目标平台,Unity 可以构建 Android 适用的 .apk 文件或 Windows 适用的 .exe 文件。由于我们没有使用 Oculus 集成项目包,应用可能无法在 Meta Quest 控制器上运行。
  1. 保存场景。
  2. 前往 File(文件)> Build And Run(构建并运行)。
  3. 双击文件,在电脑上运行应用。使用键盘或 Unity 兼容的摇杆输入。