【unity小技巧】unity最完美的CharacterController 3d角色控制器,实现移动、跳跃、下蹲、奔跑、上下坡、物理碰撞效果,复制粘贴即用

您所在的位置:网站首页 gta5人物下蹲卧倒怎么弄 【unity小技巧】unity最完美的CharacterController 3d角色控制器,实现移动、跳跃、下蹲、奔跑、上下坡、物理碰撞效果,复制粘贴即用

【unity小技巧】unity最完美的CharacterController 3d角色控制器,实现移动、跳跃、下蹲、奔跑、上下坡、物理碰撞效果,复制粘贴即用

2024-07-10 12:03| 来源: 网络整理| 查看: 265

最终效果

在这里插入图片描述

文章目录 最终效果前言为什么使用CharacterControllerSimpleMove和Move如何选择?1. SimpleMove2. Move 配置CharacterController参数控制相机移动跳跃方式一方式二 下蹲处理下坡抖动问题实现奔跑和不同移速控制完整代码补充,简单版本 实现物理碰撞效果(2024/01/02补充)完结

前言

其实一开始我是不打算写的,我感觉这种简单的功能,网上应该随便一搜一大堆,但是实际去搜会发现网上很多都是复制粘贴,要么没有实操过,要么就是功能不全,或者毫无解释的把代码丢出来,所以特地花时间去研究了研究,下面是记录我的一些思路过程,希望对你有帮助。

其实之前实战有做过FPS移动控制,只是没有说的很全面,感兴趣可以查看之前的文章: 【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1

为什么使用CharacterController

Unity中常用的三种角色移动方式如下:

使用刚体(Rigidbody)组件:这种方式将角色对象添加刚体组件,并通过力(Force)或者速度(Velocity)来控制移动。你可以使用输入控制器(例如键盘、手柄)获取移动输入,然后将对应的力或速度施加给角色刚体,从而实现移动。

使用Transform组件的Translate方法:这种方式直接使用Transform组件的Translate方法来移动角色。你可以通过获取输入控制器的输入,计算出移动方向和距离,然后调用Translate方法将角色移动到指定位置。

使用Character Controller组件:这种方式需要将角色对象添加Character Controller组件,并使用Character Controller提供的Move方法来移动角色。你可以通过输入控制器获取移动输入,然后将输入转换为移动向量,并传递给Character Controller的Move方法来实现移动。

刚体自带重力和物理效果,但是对于爬坡,走楼梯要单独处理,比较麻烦。(ps:当然,后面有机会我在研究Rigidbody如何控制人物,可以关注期待一下)

Transform呢,不带重力又不带碰撞,移动不受物理引擎控制,可能导致穿透墙壁或其他对象。不支持碰撞和重力等物理效果。所以我是直接pass的

CharacterController主要是不适用于需要处理复杂物理交互的情况,例如推动物体等。但是对于爬坡,楼梯自带了处理方式,完美解决了刚体的痛点,而如果你想推动物体也可以直接给物体一个推力即可解决(文章最后面我分享解决方案)

SimpleMove和Move如何选择?

而对于CharacterController有用两种移动实现方式,SimpleMove和Move。

1. SimpleMove 不受Y轴速度影响,自带重力效果,无法实现跳跃功能返回值为Bool,当角色接触地面返回True,反之为False。SimpleMove方法是CharacterController组件提供的一个用于处理角色平面移动的简化方法,它自动处理了角色与地面的碰撞* 检测和摩擦,但它不支持跳跃等垂直方向的动作 2. Move 无重力效果,自行实现重力,可做跳跃功能返回值(CollisionFlags对象),返回角色与物体碰撞的信息

可以看到SimpleMove看着虽好,但是最大的痛点是无法实现跳跃,所以我们只能忍痛Pass掉

配置CharacterController参数

新增一个胶囊体,代表角色,在角色身上新增CharacterController组件,参数配置如下 在这里插入图片描述

控制相机

将相机拖入为玩家的子物体,放置在角色的头部位置,修改 新增MouseLook脚本,挂载在相机上,控制相机视角

public class MouseLook : MonoBehaviour { // 鼠标灵敏度 public float mouseSensitivity = 1000f; // 玩家的身体Transform组件,用于旋转 public Transform playerBody; // x轴的旋转角度 float xRotation = 0f; void Start() { // 锁定光标到屏幕中心,并隐藏光标 Cursor.lockState = CursorLockMode.Locked; } // Update在每一帧调用 void Update() { // 执行自由视角查看功能 FreeLook(); } // 自由视角查看功能的实现 void FreeLook() { // 获取鼠标X轴和Y轴的移动量,乘以灵敏度和时间,得到平滑的移动速率 float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime; float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime; //限制旋转角度在-90到90度之间,防止过度翻转 xRotation = Mathf.Clamp(xRotation, -90f, 90f); // 累计x轴上的旋转量 xRotation -= mouseY; // 应用摄像头的x轴旋转 transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f); // 应用玩家身体的y轴旋转 playerBody.Rotate(Vector3.up * mouseX); } }

效果 在这里插入图片描述

移动

经过上面的分享,我们使用Move实现一下人物的移动 新增MovementScript脚本,挂载在角色身上

public class MovementScript : MonoBehaviour { [Tooltip("角色控制器")] public CharacterController characterController; private float horizontal; private float vertical; [Header("移动")] [Tooltip("角色行走的速度")] public float walkSpeed = 6f; [Tooltip("当前速度")] private float speed; [Tooltip("角色移动的方向")] private Vector3 moveDirection; void Start() { speed = walkSpeed; } void Update() { horizontal = Input.GetAxis("Horizontal"); vertical = Input.GetAxis("Vertical"); moveDirection = transform.right * horizontal + transform.forward * vertical; // 计算移动方向 //将该向量从局部坐标系转换为世界坐标系,得到最终的移动方向,效果和上面的一样 // moveDirection = transform.TransformDirection(new Vector3(h, 0, v)); moveDirection = moveDirection.normalized; // 归一化移动方向,避免斜向移动速度过快 characterController.Move(moveDirection * Time.deltaTime * speed); } }

效果 在这里插入图片描述

跳跃 方式一

补充:使用CharaterController.IsGrounded实现地面检测,更加简单,但是这个方式虽然简单,但是下坡时检测可能出现问题,导致跳不起来(也可能是我使用方式不对),如果你不在乎这个影响,可以酌情选择,因为它的使用真的很简单

void Update(){ //地面检测 isGround = characterController.isGrounded; SetJump(); } //控制跳跃 void SetJump() { bool jump = Input.GetButtonDown("Jump"); if (isGround) { // 在着地时阻止垂直速度无限下降 if (_verticalVelocity


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3