Files
BA-VitePress-Pages/posts/studycase1.md
2025-11-26 15:32:18 +08:00

6.4 KiB
Raw Blame History

title, date, tags, pinned, head
title date tags pinned head
StudyCase1 2025-11-25 15:35
studycase
unity
true
meta
name content
description vitepress-theme-bluearchive StudyCase1
meta
name content
keywords vitepress theme bluearchive StudyCase1

第三人称角色控制器

编辑器

  • Unity 2022.3.62f2
  • Visual Studio 2022

课程目标

  • 鼠标控制视角旋转
  • WASD控制模型移动
  • 空格控制跳跃

演示视频

课前准备

新建项目

  • 创建URP项目
  • 移除Readme
  • 新建场景或者修改初始场景为StudyCase1

安装 Input System 与 Cinemachine

  • 打开 Package Manager
  • 切换到 Unity Registry
  • 安装 Input SystemCinemachine
  • 导入示例
  • 创建初始场景(StudyCase1)
  • 从示例项目导入模型到场景

提示:安装 Input System 后Unity 会提示重启并切换至新输入系统,务必确认。

课堂任务

添加虚拟相机根节点

  • 为相机添加 CinemachineBrain作为根节点以便统一控制

创建玩家节点

  • 创建 Player 空节点,创建ForwardModel空节点并作为Player子节点以及虚拟相机
  • 注意ForwardModel的尽量不要有偏移
  • 创建胶囊体和正方体作为Model的子物体,可以去掉碰撞器,尽量不要有偏移

配置虚拟相机

  • 将虚拟相机 FollowLookAt 指向玩家模型,调整 Body/ Aim使镜头保持第三人称视角

创建 InputActions

  • 在项目窗口右键 Create > Input Actions,命名为 PlayerInputActions
  • 创建 Player Action Map添加 MoveVector2JumpButton
  • Move 绑定 WASD Jump 绑定 space

编写脚本ThirdCharacterController.cs

  • Assets\Scripts\StudyCase1 下创建脚本 ThirdCharacterController
using UnityEngine;
using UnityEngine.InputSystem;

namespace StudyCase1
{
    public class ThirdCharacterController : MonoBehaviour
    {
        public CharacterController characterController;
        public Transform forward;
        public Transform model;
        public Cinemachine.CinemachineVirtualCamera vCam;
        public float moveSpeed = 5f;
        public float jumpSpeed = 2f;
        public float turnSpeed = 10f;
        public float gravity = 10f;
        Vector3 moveDir;
        Vector2 moveInput;
        private void Update()
        {
            moveDir = new Vector3(moveInput.x, moveDir.y, moveInput.y);
            forward.eulerAngles = new Vector3(0, vCam.transform.eulerAngles.y, 0);
            moveDir = forward.TransformDirection(moveDir);
            if (moveInput != Vector2.zero)
            {
                Quaternion target = Quaternion.LookRotation(new Vector3(moveDir.x, 0, moveDir.z));
                model.rotation = Quaternion.Slerp(model.rotation, target, turnSpeed * Time.deltaTime);
            }
            if (!characterController.isGrounded)
                moveDir.y -= gravity * Time.deltaTime;
            characterController.Move(moveDir * moveSpeed * Time.deltaTime);
        }
        public void OnMove(InputAction.CallbackContext context)
        {
            if (characterController.isGrounded)
                moveInput = context.ReadValue<Vector2>();
            else moveInput = Vector2.zero;
        }
        public void OnJump(InputAction.CallbackContext context)
        {
            if (context.performed && characterController.isGrounded)
            {
                moveDir.y = jumpSpeed;
            }
        }
    }
}

代码讲解

  • namespace StudyCase1:因为可能出现同名文件
  • forward:作为“参照物”同步虚拟相机的 Y 轴旋转,用来转换输入的坐标轴。
  • moveDir:在本地坐标系下计算移动向量,并通过 CharacterController.Move 驱动。
  • OnMove/OnJump:直接使用 Input System 回调,确保只有在贴地时才写入输入,避免空中漂移。
  • 旋转插值Quaternion.Slerp 让角色转身更加顺滑,可根据手感微调 turnSpeed

Player节点设置

  • 挂载ThirdCharacterController
  • 添加组件PlayerInput

常见问题速查

  • 角色不动:确认 CharacterController 已赋值且 Move Action Map 激活。
  • 镜头不同步:检查 forward 对象是否正确引用虚拟相机的朝向,检查模型和player是否偏移过大。
  • 跳跃失效:确认 Jump 绑定的动作类型为 Button,确认角色是否在地上。
  • 移动时会旋转镜头:确认虚拟相机是在 Player 节点下,不是在 Model 节点下。

完成以上步骤,即可得到一个可拓展的第三人称基础模板。项目地址