开发

开始构建首个 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)。
    Unity Inspector showing Albedo color picker set to a dark blue color for the floor material.
  4. 重复第 2 步至第 4 步,为墙壁、玩家球和碰撞时墙壁的颜色变化创建材质。将这些材质重命名为 wall-color(墙壁颜色)、ball-color(球颜色)和 after-collision(碰撞后),将 RGB 值分别设为 (255,255,255)、(240,240,0) 和 (241,107,8)。
    Unity Project view with four materials: floor-color, wall-color, ball-color, and after-collision.

第 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. 地面颜色材质拖放到平面上以上色。
    5. Drag and drop the *floor-color* material on the plane to illustration.
玩家球
  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)。
    4. In the **Inspector** view, under **Transform**, ensure th illustration.
四面墙
  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)
    fourth-wall illustration

第 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(刚体)。
    Unity Inspector showing the Rigidbody component added to the player-ball GameObject.
    b.点击 Add Component(添加组件)> New Script(新脚本),将其命名为 PlayerController,然后点击 Create and Add(创建并添加)。
    c.点击 PlayerController 脚本旁边的齿轮图标,然后点击 Edit Script(编辑脚本),在代码编辑器中打开脚本。
    Unity Inspector with the PlayerController script gear menu open and Edit Script highlighted.
    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 脚本中声明的速度变量相同。
    Unity Inspector showing the PlayerController script with the Speed field set to 500.
  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 脚本中声明的字段相同。
    Unity Inspector showing the ColorController script with Wall Material and Display Text fields.
  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 兼容的摇杆输入。