【unity实战】使用新版输入系统Input System+Rigidbody实现第三人称人物控制器(附项目源码)
最终效果

前言
使用CharacterController实现3d角色控制器,之前已经做过很多了:
【unity小技巧】unity最完美的CharacterController 3d角色控制器,实现移动、跳跃、下蹲、奔跑、上下坡、物理碰撞效果,复制粘贴即用
【unity实战】Cinemachine虚拟相机+Character Controller实现俯视角、第三人称角色控制,复制粘贴即用
有的人就会问了,使用Rigidbody要怎么做呢?这不就来了,本文主要是使用新版输入系统Input System+Rigidbody实现第三人称人物控制器,我就不做特别复杂了,其他内容欢迎大家自行补充。因为我也不是很推荐大家使用Rigidbody,CharacterController 其实已经可以满足我们开发中的所有需求了。Rigidbody定义一些CharacterController自带的功能真的非常麻烦,比如爬坡,走楼梯等等,所以我这里主要只是带大家了解一下,并不会深入研究。
使用Input System获取玩家输入
参考:【推荐100个unity插件之18】Unity 新版输入系统Input System的使用,看这篇就够了
我这里直接使用Player Input组件,生成的默认的Input Actions映射

新增脚本获取玩家输入
/// <summary>
/// 玩家输入
/// </summary>
public class PlayerInput : MonoBehaviour
{// 用于存储移动输入的向量public Vector2 MoveInput { get; private set; }// 用于存储视角输入的向量public Vector2 LookInput { get; private set; }public bool ChangeCameraWasPressedThisFrame{get; private set; }//是否按下切换相机private InputActions _input;private void OnEnable(){_input = new InputActions();_input.Player.Enable();_input.Player.Move.performed += SetMove;_input.Player.Move.canceled += SetMove;_input.Player.Look.performed += SetLook;_input.Player.Look.canceled += SetLook;}private void OnDisable(){_input.Player.Move.performed -= SetMove;_input.Player.Move.canceled -= SetMove;_input.Player.Look.performed -= SetLook;_input.Player.Look.canceled -= SetLook;_input.Player.Disable(); }private void SetMove(InputAction.CallbackContext context){MoveInput = context.ReadValue<Vector2>();}private void SetLook(InputAction.CallbackContext context){LookInput = context.ReadValue<Vector2>();}
}
人物添加刚体
添加刚体,配置参数

控制角色移动
新增脚本控制角色移动,对这里的AddRelativeForce不太了解的小伙伴可以查看我这篇文章:
【unity小技巧】常用的方法属性和技巧汇总(长期更新)

public class PlayerController : PlayerInput
{Rigidbody _rb;[Header("移动")][SerializeField] float _speed= 1000f;// 移动的速度private void Awake(){_rb = GetComponent<Rigidbody>();}private void FixedUpdate(){PlayerMove();}// 计算并应用玩家的移动private void PlayerMove(){// 根据输入和速度计算移动向量_playerMoveInput = new Vector3(MoveInput.x, 0, MoveInput.y).normalized * _speed;// 将相对力应用到刚体上_rb.AddRelativeForce(_playerMoveInput, ForceMode.Force);}
}
配置

效果

手搓代码控制相机视角
修改PlayerInput
[Header("相机视角控制")]
public Transform CameraFollow;// 用于跟随摄像机的 Transform
private Vector3 _playerLookInput;// 玩家视角输入
private float _playerRotation;// 角色旋转角度
private float _cameraPitch;// 摄像机俯仰角度
[SerializeField] float _rotationSpeed = 180.0f;// 角色旋转速度
[SerializeField] float _pitchSpeed = 180.0f;// 摄像机俯仰速度private void Awake()
{_rb = GetComponent<Rigidbody>();mainCamera = Camera.main; // 获取主相机
}private void Update()
{_playerLookInput = new Vector3(LookInput.x, -LookInput.y, 0f) * Time.deltaTime;// 获取视角输入PlayerLook(); // 更新角色的旋转PitchCamera(); // 更新摄像机的俯仰角度
}// 更新角色的旋转
private void PlayerLook()
{_playerRotation += _playerLookInput.x * _rotationSpeed;_rb.rotation = Quaternion.Euler(0f, _playerRotation, 0f);
}// 更新摄像机的俯仰角度
private void PitchCamera()
{Vector3 rotationValues = CameraFollow.rotation.eulerAngles;_cameraPitch += _playerLookInput.y * _pitchSpeed;_cameraPitch = Mathf.Clamp(_cameraPitch, -89.9f, 89.9f);//限制俯仰视角角度CameraFollow.rotation = Quaternion.Euler(_cameraPitch, rotationValues.y, rotationValues.z);
}
配置相机为角色的子物体

效果

最终代码
using UnityEngine;public class PlayerController : PlayerInput
{Rigidbody _rb;[Header("移动")]Vector3 _playerMoveInput;// 玩家移动向量[SerializeField] float _speed = 1000f;// 移动的速度[Header("相机视角控制")]public Transform CameraFollow;// 用于跟随摄像机的 Transformsprivate Vector3 _playerLookInput;// 玩家视角输入private float _playerRotation;// 角色旋转角度private float _cameraPitch;// 摄像机俯仰角度[SerializeField] float _rotationSpeed = 180.0f;// 角色旋转速度[SerializeField] float _pitchSpeed = 180.0f;// 摄像机俯仰速度private Camera mainCamera; // 主相机private void Awake(){_rb = GetComponent<Rigidbody>();mainCamera = Camera.main; // 获取主相机}private void Update(){_playerLookInput = new Vector3(LookInput.x, -LookInput.y, 0f) * Time.deltaTime;// 获取视角输入PlayerLook(); // 更新角色的旋转PitchCamera(); // 更新摄像机的俯仰角度}private void FixedUpdate(){PlayerMove();}// 计算并应用玩家的移动private void PlayerMove(){// 根据输入和速度计算移动向量_playerMoveInput = new Vector3(MoveInput.x, 0, MoveInput.y).normalized * _speed;// 将相对力应用到刚体上_rb.AddRelativeForce(_playerMoveInput, ForceMode.Force);}// 更新角色的旋转private void PlayerLook(){_playerRotation += _playerLookInput.x * _rotationSpeed;_rb.rotation = Quaternion.Euler(0f, _playerRotation, 0f);}// 更新摄像机的俯仰角度private void PitchCamera(){Vector3 rotationValues = CameraFollow.rotation.eulerAngles;_cameraPitch += _playerLookInput.y * _pitchSpeed;_cameraPitch = Mathf.Clamp(_cameraPitch, -89.9f, 89.9f);//限制俯仰视角角度CameraFollow.rotation = Quaternion.Euler(_cameraPitch, rotationValues.y, rotationValues.z);}
}
源码
很遗憾源码我并不想
免费分享,我也建议大家能自己手动去敲代码,逐步实现和理解每一块功能。项目实现所涉及的主要功能思路和代码我也已经毫无保留的分享在文章中了,当然,如果你真的需要的话,源码我也放出来了,收个辛苦费,就当作你对我不断创作的支持。力量随微,心暖人。您的每一次支持都是我创作的最大动力!!!
https://gf.bilibili.com/item/detail/1106435120
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!
好了,我是向宇,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

相关文章:
【unity实战】使用新版输入系统Input System+Rigidbody实现第三人称人物控制器(附项目源码)
最终效果 前言 使用CharacterController实现3d角色控制器,之前已经做过很多了: 【unity小技巧】unity最完美的CharacterController 3d角色控制器,实现移动、跳跃、下蹲、奔跑、上下坡、物理碰撞效果,复制粘贴即用 【unity实战】C…...
代码随想录算法训练营Day03 | 链表理论基础、203.移除链表元素 、707.设计链表、206.反转链表
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 链表理论基础203.移除链表元素思路与重点 707.设计链表思路与重点 206.反转链表思路与重点 链表理论基础 C/C的定义链表节点方式: // 单链表 struct L…...
【总结】CSS(SCSS) 不常用属性
1、设置 antd Meta 组件中 title 过长自动换行: .ant-card-meta-title {white-space: normal; /* 允许文本换行 */overflow: visible; /* 防止内容被截断 */text-overflow: clip; /* 禁用文本省略号 */} 2、选择器书写: .QR {&:hover {}} 3、设置文…...
电位计的模拟
该电位计的内部电阻在 270 范围内以“几乎”线性的方式从大约 15 欧姆变化到 220 欧姆。该设备的电流和电阻特性如下表所示: 计算曲线拟合以插入电位计欧姆电阻的非线性趋势非常简单。电位曲线如下: R16.2145((1.55848sqrt(x))*sin((-0.038222)*(-45.77…...
OSI七层网络协议
1、OSI各层数据的名称 7-5,应用层、表示层、会话层都叫做协议数据单元(PDU, Protocol Data Unit)。 4,传输层叫数据段(Segment)。 3,网络层叫数据包/报文(Packet)。 2,数据链路层叫数据帧(Frame)。 1,物理层叫比特流(…...
U盘提示需要格式化才能使用怎么办?教你轻松应对
U盘作为一种便捷的数据存储设备,广泛应用于日常工作和生活中。然而,有时我们会遇到U盘插入电脑后提示需要格式化才能使用的情况,这让人倍感焦虑,因为格式化往往意味着数据丢失。不过,在采取极端措施之前,我…...
Atom编辑器:曾经的效率提升利器,终将被新技术取代
Atom编辑器:曾经的效率提升利器,终将被新技术取代 哪个编程工具让你的工作效率翻倍 ? 那么对我来说答案是 Atom。 作为一名Python开发者,我一直依赖Atom编辑器进行日常编程工作。在漫长的开发旅程中,Atom成为了我代码…...
立创商城9.9免邮活动开始啦!
从9月2日起,立创商城推出免邮活动,每月在领券中心>精选专区领取免邮券,即可享受满9.9元使用免邮券服务。 未注册的用户,可扫描下方二维码注册哦~...
图形几何-如何将凹多边形分解成若干个凸多边形
凹多边形的概念 凹多边形是指至少有一个内角大于180度的多边形。与之相对,凸多边形的所有内角均小于或等于180度,且任意两点之间的连线都完全位于多边形内部。将凹多边形分解成若干个凸多边形是计算几何中的一个重要问题。 分解原理 将凹多边形分解为凸…...
一个php快速项目搭建框架源码,带一键CURD等功能
介绍: 框架易于功能扩展,代码维护,方便二次开发,帮助开发者简单高效降低二次开发成本,满足专注业务深度开发的需求。 百度网盘下载 图片:...
STM32基础篇:RTC × Unix时间戳 × BKP
Unix时间戳 最早是在Unix系统使用的,之后很多由Unix演变而来的系统也都继承了Unix时间戳的规定。目前,Linux、Windows、安卓这些系统,其底层的计时系统都是使用Unix时间戳。 Uinx时间戳(Unix Timestamp)定义为从UTC/…...
Recyclerview部分列固定部分列滑动学习备忘
安卓使用RecyclerViewHorizontalScrollView 实现Item整体横向滑动 - 简书 (jianshu.com)https://www.jianshu.com/p/75bba86dd61c Android仿同花顺自选股列表控件介绍 RecyclerView的开发中,我们通常会遇到一行显示不下内容的情况,产品会 - 掘金 (jueji…...
【Python】路径(绝对路径、相对路径,当前工作目录),模块搜索路径(添加),Python安装路径,补充:cmd(命令行窗口)运行Python文件
Python中经常用到路径,比如:文件路径(读取文件,保存文件等),模块搜索路径(导入其他模块),Python安装路径。 而路径有两种:绝对路径,相对路径。在…...
Oceanbase 透明加密TDE
官方文档:数据库透明加密概述-V4.3.2-OceanBase 数据库文档-分布式数据库使用文档 OceanBase 数据库社区版暂不支持数据透明加密。 数据存储加密是指对数据和 Clog 等保存在磁盘中的数据进行无感知的加密,即透明加密(简称 TDE)。…...
图像去噪实验:基于全变分(TV)模型的MATLAB实现
一、背景 全变分模型在图像处理领域中被广泛用于去除噪声,同时保持图像边缘的清晰度。 二、实验步骤 图像的读取、噪声添加、去噪处理以及结果的显示。 三、实验仿真结果图 四、结论 全变分模型是一种有效的图像去噪方法,它能够在去除噪声的同时&#…...
97.WEB渗透测试-信息收集-Google语法(11)
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于: 易锦网校会员专享课 上一个内容:96.WEB渗透测试-信息收集-Google语法(10) 2 、找上传类漏洞地址&…...
连锁美业门店如何寻找精准客户?美业SaaS拓客系统管理系统源码
连锁美业门店要寻找精准客户,可以采取多种方法结合现实因素进行推广和营销。以下是博弈美业系统给出的一些建议: 1.定位目标客户群体: 首先,门店需要确定目标客户是谁。这可能包括年龄、性别、收入水平、生活方式以及消费习惯等…...
RK3588开发板利用udp发送和接收数据
目录 1 send.cpp 2 receive.cpp 3 编译运行 4 测试 1 send.cpp #include <iostream> #include <string> #include <cstring> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> //…...
代码整洁之道(第3章节)--函数
目录 3.1 短小 3.2 只做一件事 3.3 每个函数一个抽象层级 3.4switch语句 3.5 使用描述性的名称 3.6 函数参数 3.6.1 一元函数的普遍形式 3.6.2标识参数 3.6.3 二元函数 3.6.4 三元函数 3.6.5参数对象 3.6.6参数列表 3.6.7动词与关键字 3.8分隔指令与询问 3.9使用…...
92. UE5 GAS RPG 使用C++创建GE实现灼烧的负面效果
在正常游戏里,有些伤害技能会携带一些负面效果,比如火焰伤害的技能会携带燃烧效果,敌人在受到伤害后,会接受一个燃烧的效果,燃烧效果会在敌人身上持续一段时间,并且持续受到火焰灼烧。 我们将在这一篇文章里…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
aardio 自动识别验证码输入
技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”,于是尝试整合图像识别与网页自动化技术,完成了这套模拟登录流程。核心思路是:截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...
CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...
