杰瑞科技汇

Unity3D漫游教程如何快速上手?

Unity 3D 漫游终极教程:从零开始打造沉浸式体验

漫游是游戏、建筑可视化、虚拟现实等领域中非常核心的功能,本教程将带你一步步掌握 Unity 中实现漫游的各种技术。

Unity3D漫游教程如何快速上手?-图1
(图片来源网络,侵删)

目录

  1. 第一部分:基础概念与准备工作
    • 1 什么是漫游?
    • 2 核心组件介绍
    • 3 场景搭建基础
  2. 第二部分:第一人称漫游
    • 1 创建玩家角色
    • 2 实现角色移动
    • 3 实现视角旋转
    • 4 整合与优化
  3. 第三部分:第三人称漫游
    • 1 创建角色与相机
    • 2 实现角色移动
    • 3 实现相机跟随
    • 4 整合与优化
  4. 第四部分:自动漫游/路径漫游
    • 1 使用 Navmesh 实现自动寻路
    • 2 使用 Waypoints 实现路径漫游
  5. 第五部分:进阶技巧与优化
    • 1 添加交互功能
    • 2 音效与背景音乐
    • 3 性能优化
    • 4 输入管理

第一部分:基础概念与准备工作

1 什么是漫游?

漫游指的是用户可以在一个三维虚拟环境中自由地移动、观察和探索,核心是控制视角

2 核心组件介绍

在开始之前,你需要了解几个核心组件:

  • Transform: 所有 GameObject 的基础组件,定义了物体的位置、旋转和缩放,这是最最核心的组件。
  • Rigidbody (刚体): 使物体受物理影响,如重力、碰撞,对于玩家角色,通常需要它来实现真实的物理反馈。
  • Collider (碰撞体): 定义物体的物理形状,用于检测碰撞和触发事件,常用 Box Collider (盒型碰撞体) 或 Capsule Collider (胶囊碰撞体)。
  • CharacterController (角色控制器): Unity 提供的一个专门用于角色移动的组件,它内置了移动、重力、碰撞检测等功能,比手动用 Rigidbody 更简单。
  • Camera (相机): 玩家的“眼睛”,你可以控制相机的位置和旋转,来改变玩家的视角。
  • Animator (动画器): 用于控制角色的动画,如行走、跑步等。

3 场景搭建基础

  1. 创建新项目: 打开 Unity Hub,创建一个新的 3D 项目。
  2. 导入资源: 你可以从 Unity Asset Store 导入一些免费的 3D 模型(如 Standard Assets)或自己创建一些简单的几何体(如 Cube, Plane)来搭建一个测试场景。
  3. 创建地面: 创建一个 Plane (平面),作为地面。
  4. 创建墙壁: 创建几个 Cube (立方体),调整它们的位置和大小,搭建出简单的墙壁。
  5. 创建玩家: 我们将在下一步创建。

第二部分:第一人称漫游

这是最经典的漫游方式,玩家通过角色的眼睛来观察世界。

1 创建玩家角色

  1. Hierarchy 窗口,右键 -> 3D Object -> Capsule,这将作为我们的玩家模型。
  2. 选中这个 Capsule,在 Inspector 窗口将其 Tag 设置为 Player
  3. 添加相机: 在 Hierarchy 窗口,右键 Capsule -> Camera,这样相机就成为了 Capsule 的子对象,会随着胶囊一起移动。
  4. 调整相机位置: 选中 Main Camera,调整其 Position(X: 0, Y: 0.7, Z: 0)Rotation(X: 0, Y: 0, Z: 0),这样相机就位于角色的头部高度。
  5. 隐藏胶囊模型: 选中 Capsule,取消勾选 Mesh Renderer 组件,因为我们不需要看到它,我们只通过相机看世界。

2 实现角色移动

我们将使用 CharacterController 组件,因为它非常简单且效果不错。

Unity3D漫游教程如何快速上手?-图2
(图片来源网络,侵删)
  1. 选中 Capsule (玩家),点击 Add Component,添加 Character Controller
  2. 调整 Character Controller 的参数:
    • Center: (0, 0.9, 0) (让控制器中心在角色脚下)
    • Radius: 2
    • Height: 8
  3. 创建一个新的 C# 脚本,命名为 FirstPersonMovement
  4. 将脚本拖拽到 Capsule (玩家) 上。
  5. 打开脚本,编写以下代码:
using UnityEngine;
public class FirstPersonMovement : MonoBehaviour
{
    public CharacterController controller;
    public float speed = 6f;
    void Update()
    {
        // 获取水平和垂直输入 (WASD 或 方向键)
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
        // 计算移动方向
        Vector3 move = transform.right * horizontal + transform.forward * vertical;
        // CharacterController 的 SimpleMove 函数会自动应用重力
        controller.SimpleMove(move * speed);
    }
}
  • 代码解释:
    • Input.GetAxis("Horizontal") 获取 A/D 或 左/右方向键的输入值(-1 到 1)。
    • Input.GetAxis("Vertical") 获取 W/S 或 上/下方向键的输入值。
    • transform.righttransform.forward 是基于角色当前朝向的右前方向量,这样移动方向就是角色面向的方向,而不是世界坐标的固定方向。
    • controller.SimpleMove() 会自动应用重力,并确保移动时不会穿过其他物体。

3 实现视角旋转

这个脚本将控制相机的上下左右旋转。

  1. 创建一个新的 C# 脚本,命名为 MouseLook
  2. 将脚本拖拽到 Main Camera 上。
  3. 打开脚本,编写代码:
using UnityEngine;
public class MouseLook : MonoBehaviour
{
    public float mouseSensitivity = 100f;
    public Transform playerBody; // 需要拖拽玩家胶囊体到这里
    private float xRotation = 0f;
    void Start()
    {
        // 锁定鼠标光标
        Cursor.lockState = CursorLockMode.Locked;
    }
    void Update()
    {
        // 获取鼠标输入
        float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
        float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
        // 控制相机上下旋转 (俯仰)
        xRotation -= mouseY;
        xRotation = Mathf.Clamp(xRotation, -90f, 90f); // 限制视角不能翻转过头
        transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
        // 控制玩家左右旋转 (偏航)
        playerBody.Rotate(Vector3.up * mouseX);
    }
}
  • 代码解释:
    • Inspector 窗口中,你需要将 Capsule (玩家) 拖拽到 Mouse Look 脚本的 Player Body 字段里。
    • Cursor.lockState = CursorLockMode.Locked; 会将鼠标光标锁定在屏幕中央,实现无边界旋转。
    • mouseX 控制整个玩家物体的旋转,实现左右转头。
    • mouseY 控制相机自身的旋转,实现上下看。Mathf.Clamp 用于限制视角,避免“托马斯全旋”。

4 整合与优化

你的第一人称漫游系统已经基本完成了!运行游戏,你就可以用 WASD 移动,用鼠标控制视角了。


第三部分:第三人称漫游

第三人称漫游可以看到自己的角色模型,并且相机通常会跟随在角色后方。

1 创建角色与相机

  1. 创建角色: 创建一个 Capsule 或导入一个 3D 角色模型,设置 TagPlayer
  2. 创建相机: 创建一个空的 GameObject,命名为 ThirdPersonCamera,这个物体将作为相机的父节点,方便我们控制相机围绕角色旋转。
  3. ThirdPersonCamera 下创建一个 Main Camera
  4. 调整 ThirdPersonCamera 的位置,(0, 2, -5),这表示相机在角色后方5米,上方2米的位置。
  5. 调整 Main CameraRotation(0, 0, 0),让它看向角色。

2 实现角色移动

移动逻辑和第一人称类似,但相机控制不同。

Unity3D漫游教程如何快速上手?-图3
(图片来源网络,侵删)
  1. 为角色添加 CharacterController
  2. 创建一个 ThirdPersonMovement 脚本,代码与 FirstPersonMovement 基本相同,但不需要引用相机。
// ThirdPersonMovement.cs (代码与 FirstPersonMovement.cs 几乎一样)
using UnityEngine;
public class ThirdPersonMovement : MonoBehaviour
{
    public CharacterController controller;
    public float speed = 6f;
    void Update()
    {
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
        Vector3 move = transform.right * horizontal + transform.forward * vertical;
        controller.SimpleMove(move * speed);
    }
}

3 实现相机跟随

这是第三人称的核心,相机需要平滑地跟随角色,并能通过鼠标控制围绕角色旋转。

  1. 创建一个 ThirdPersonCameraController 脚本。
  2. 将脚本拖拽到 ThirdPersonCamera 这个空物体上。
  3. 打开脚本,编写代码:
using UnityEngine;
public class ThirdPersonCameraController : MonoBehaviour
{
    public Transform player; // 拖拽玩家角色到这里
    public float distance = 5.0f;
    public float height = 2.0f;
    public float smoothSpeed = 0.125f;
    public float mouseSensitivity = 2.0f;
    private float currentX = 0.0f;
    private float currentY = 0.0f;
    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
    }
    void Update()
    {
        // 获取鼠标输入来旋转相机
        currentX += Input.GetAxis("Mouse X") * mouseSensitivity;
        currentY -= Input.GetAxis("Mouse Y") * mouseSensitivity;
        currentY = Mathf.Clamp(currentY, -30f, 60f); // 限制上下旋转角度
    }
    void LateUpdate()
    {
        // 计算目标位置
        Vector3 desiredPosition = player.position;
        desiredPosition += Quaternion.Euler(currentY, currentX, 0) * new Vector3(0, height, -distance);
        // 平滑移动相机
        transform.position = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
        transform.LookAt(player.position + new Vector3(0, height/2, 0)); // 让相机看向角色的上半身
    }
}
  • 代码解释:
    • Update() 函数处理鼠标输入,计算相机的水平(currentX)和垂直(currentY)旋转角度。
    • LateUpdate() 在所有 Update() 执行完后运行,是更新相机位置的绝佳时机,可以避免抖动。
    • desiredPosition 根据玩家的位置、鼠标偏移量和预设的 distanceheight 计算出相机应该在的目标位置。
    • Vector3.Lerp 实现相机的平滑跟随,而不是瞬间移动。
    • transform.LookAt() 让相机始终看向角色。

4 整合与优化

ThirdPersonCameraController 脚本中的 Player 字段拖拽到你的角色模型上,运行游戏,你就可以用 WASD 移动,用鼠标控制视角了。


第四部分:自动漫游/路径漫游

当需要制作演示或特定路径的探索时,自动漫游非常有用。

1 使用 Navmesh 实现自动寻路

这是最灵活的方式,AI 可以自动避开障碍物。

  1. 烘焙 Navmesh:
    • 选中你的地面和所有静态障碍物(墙壁等),在 Inspector 中勾选 Navigation Static
    • 点击顶部菜单 Window -> Navigation,打开导航窗口。
    • Baking 标签页,点击 Bake 按钮,Unity 会生成一个蓝色的导航网格。
  2. 创建 AI 控制器:
    • 创建一个 Capsule 作为自动漫游的角色。
    • 添加 Navmesh Agent 组件。
    • 创建一个 AutoRoamer 脚本。
using UnityEngine;
using UnityEngine.AI;
public class AutoRoamer : MonoBehaviour
{
    public NavMeshAgent agent;
    public Transform[] waypoints; // 在 Inspector 中手动设置路径点
    private int currentWaypointIndex = 0;
    void Start()
    {
        if (waypoints.Length > 0)
        {
            agent.SetDestination(waypoints[currentWaypointIndex].position);
        }
    }
    void Update()
    {
        if (!agent.pathPending && agent.remainingDistance < 0.5f)
        {
            // 到达当前路径点,前往下一个
            currentWaypointIndex = (currentWaypointIndex + 1) % waypoints.Length;
            agent.SetDestination(waypoints[currentWaypointIndex].position);
        }
    }
}
  • 使用方法:
    • 在场景中创建几个空的 GameObject 作为路径点,并调整它们的位置。
    • 将这些路径点拖拽到 AutoRoamer 脚本的 Waypoints 数组中。
    • 运行游戏,胶囊体就会自动沿着路径点移动。

2 使用 Waypoints 实现路径漫游

这是一种更简单、更直接的控制方式,不依赖 Navmesh。

using UnityEngine;
public class WaypointFollower : MonoBehaviour
{
    public Transform[] waypoints;
    public float speed = 2f;
    private int currentWaypointIndex = 0;
    void Update()
    {
        if (waypoints.Length == 0) return;
        Transform targetWaypoint = waypoints[currentWaypointIndex];
        Vector3 moveDirection = (targetWaypoint.position - transform.position).normalized;
        transform.Translate(moveDirection * speed * Time.deltaTime);
        if (Vector3.Distance(transform.position, targetWaypoint.position) < 0.1f)
        {
            currentWaypointIndex = (currentWaypointIndex + 1) % waypoints.Length;
        }
    }
}
  • 区别: 这种方式是直接 Translate 移动物体,没有碰撞检测和路径寻找,适合简单的、无障碍的路径。

第五部分:进阶技巧与优化

1 添加交互功能

  1. 创建可交互物体: 创建一个物体,比如一个门或一个按钮。
  2. 添加脚本: 为这个物体添加一个 InteractableObject.cs 脚本。
// InteractableObject.cs
using UnityEngine;
public class InteractableObject : MonoBehaviour
{
    void OnMouseDown() // 当鼠标点击时触发
    {
        Debug.Log("你点击了: " + gameObject.name);
        // 在这里添加交互逻辑,例如开门、拾取物品等
    }
}
  1. 修改第一人称脚本: 在 MouseLook.cs 中添加射线检测,以便在远处交互。
// 在 MouseLook.cs 的 Update() 函数中添加
if (Input.GetMouseButtonDown(0)) // 如果左键点击
{
    Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0)); // 从屏幕中心发射射线
    if (Physics.Raycast(ray, out RaycastHit hit))
    {
        // 检查击中的物体是否有 InteractableObject 组件
        InteractableObject interactable = hit.collider.GetComponent<InteractableObject>();
        if (interactable != null)
        {
            interactable.OnMouseDown(); // 调用交互方法
        }
    }
}

2 音效与背景音乐

  1. 导入音频文件: 将 .wav.mp3 文件拖入 Project 窗口。
  2. 创建 Audio Source: 为需要播放声音的物体(如玩家、场景)添加 Audio Source 组件。
  3. 设置 Audio Clip: 在 Audio Source 组件中,将你的音频文件拖到 AudioClip 字段。
  4. 播放音频: 你可以在脚本中通过 GetComponent<AudioSource>().Play() 来控制播放。

3 性能优化

  • LOD (Level of Detail): 为远处的模型创建不同精度的版本,减少渲染负担。
  • Occlusion Culling (遮挡剔除): 在 Window -> Rendering -> Occlusion Culling 中设置,让 Unity 自动不渲染被其他物体完全挡住的区域。
  • 对象池: 对于频繁创建和销毁的对象(如子弹、特效),使用对象池技术可以极大提升性能。

4 输入管理

对于复杂的游戏,建议使用 Unity 的 Input System 包(在 Package Manager 中安装)来管理输入,这样可以将按键操作与代码解耦,方便后期修改键位。


本教程涵盖了 Unity 3D 漫游的核心技术:

  • 第一人称: 适合 FPS 游戏、模拟器。
  • 第三人称: 适合 RPG、动作冒险游戏。
  • 自动漫游: 适合场景演示、预览。

从基础的移动和视角控制,到高级的寻路和交互,你已经掌握了构建一个完整漫游系统的能力,就是去实践、去创造属于你自己的精彩世界吧!祝你开发顺利!

分享:
扫描分享到社交APP
上一篇
下一篇