Unity 一个丝滑的3D下--XY轴2D平台跳跃--控制器模板(FSM)

news/2025/4/2 5:03:13/

        本Demo基础来自于:

【阿严】[Unity]平台跳跃游戏 角色控制器 教程合集 | 状态机架构 | Platformer Controller Tutorial Collection_哔哩哔哩_bilibili

阿严的Github地址:https://github.com/AtCloudStudio/PlatformerControllerTutorial 

我的实现:通过网盘分享的文件:3D下的2D控制器精髓.7z
链接: https://pan.baidu.com/s/1B-XHXM0a9VzVTrJbL3uctw?pwd=1234 提取码: 1234 

         本Demo的重点:

目录

1.新输入系统

2. FSM的so文件化

3.土狼时间

4.输入预处理(跳跃)


思维导图

状态机及玩家基本组件部分 

3d.png" width="1298" />

玩家具体状态实现 

3dc4a388408c863e79c9805dffc6.png" width="1495" /> 

视频介绍:

Unity 一个3D下的2D平台跳跃控制器

        因为实现起来还是比较简单无痛的 所以具体请查看源码 我只是将代码放在这里 并不会做更多的解释

1.新输入系统

using System.Collections;
using Unity.VisualScripting;
using UnityEngine;public class PlayerInput : MonoBehaviour
{private InputSystem_Actions inputActions;[SerializeField, InspectorLabel("跳跃缓冲自动无效时间")] private float jumpInputBufferTime = 0.5f;public Vector2 Axis => inputActions.Player.Move.ReadValue<Vector2>();public float MoveX_input => Axis.x;public bool isMove_input => MoveX_input != 0;public bool isJump_input => inputActions.Player.Jump.WasPerformedThisFrame();public bool StopJump_input => inputActions.Player.Jump.WasReleasedThisFrame();//土狼时间public bool hasJumpInputBuffer { get; set; }private void Awake(){inputActions = new InputSystem_Actions();}public void EnableInputSystem(){inputActions.Player.Enable();Cursor.lockState = CursorLockMode.Locked;// 注册 当玩家松开跳跃键时,就会触发canceled这个回调inputActions.Player.Jump.canceled += (de) =>{hasJumpInputBuffer = false;};}void OnGUI(){Rect rect = new Rect(200, 200, 200, 200);string message = "Has Jump Input Buffer: " + hasJumpInputBuffer;GUIStyle style = new GUIStyle();style.fontSize = 20;style.fontStyle = FontStyle.Bold;GUI.Label(rect, message, style);}public void ResetJumpBuffer(){StopCoroutine(DoRestJumpBuffer());StartCoroutine(DoRestJumpBuffer());}public IEnumerator DoRestJumpBuffer(){hasJumpInputBuffer = true;yield return new WaitForSeconds(jumpInputBufferTime);hasJumpInputBuffer = false;}public void DisableInputSystem(){inputActions.Player.Disable();}
}

2. FSM的so文件化

using UnityEngine;public class PlayerState : ScriptableObject, IState
{protected Animator animator;protected PlayerInput playerInput;protected PlyaerStateMachine playerStateMachine;protected PlayerController playerController;#region 动画参数[SerializeField] private string animationClipName; //动画名称[SerializeField, Range(0, 1f)] private float crossFadeTime = 0.1f;private int stateHash;protected float startTime;protected float StateDurtion => Time.time - startTime;protected bool IsAnimationFinished => StateDurtion >= animator.GetCurrentAnimatorStateInfo(0).length;#endregion#region 继承参数protected float currentSpeed;#endregion/// <summary>/// 初始化/// </summary>/// <param name="stateMachine">状态机对象</param>/// <param name="animator">动画组件</param>/// <param name="playerInput">玩家输入类对象</param>/// <param name="playerController">玩家控制类对象</param>public void Init(PlyaerStateMachine stateMachine, Animator animator, PlayerInput playerInput,PlayerController playerController){this.animator = animator;this.playerStateMachine = stateMachine;this.playerInput = playerInput;this.playerController = playerController;}private void OnEnable(){stateHash = Animator.StringToHash(animationClipName);}public virtual void Enter(){animator.CrossFadeInFixedTime(animationClipName, crossFadeTime);startTime = Time.time;}public virtual void Exit() { }public virtual void FixedUpdate() { }public virtual void Update() { }
}

3.土狼时间

using UnityEngine;
[CreateAssetMenu(menuName = "Player/States/Player_CoyoteTime")]
public class Player_CoyoteTime : PlayerState
{public float runSpeed = 5f;public float coyoteTime = 0.2f;public override void Enter(){base.Enter();playerController.SetUesGravity(false);}public override void Update(){//土狼时间:让玩家在空中悬浮一小段时间 还是可以跳跃if (playerInput.isJump_input){playerStateMachine.ChangeState(typeof(Player_JumpUp));}//只有在超过过土狼时间以后 或者不输入以后才会下落if (StateDurtion >= coyoteTime || !playerInput.isMove_input){playerStateMachine.ChangeState(typeof(Player_JumpFall));}}public override void FixedUpdate(){//currentSpeed同步减速playerController.Move2Clip(runSpeed);}public override void Exit(){playerController.SetUesGravity(true);}
}

4.输入预处理(跳跃)

        在PlayerInput里

    public void ResetJumpBuffer(){StopCoroutine(DoRestJumpBuffer());StartCoroutine(DoRestJumpBuffer());}public IEnumerator DoRestJumpBuffer(){hasJumpInputBuffer = true;yield return new WaitForSeconds(jumpInputBufferTime);hasJumpInputBuffer = false;}


http://www.ppmy.cn/news/1584515.html

相关文章

Android 中获取颜色资源

在 Android 开发中&#xff0c;资源&#xff08;如字符串、颜色等&#xff09;通常存储在 res 文件夹中&#xff0c;并通过资源 ID 进行访问。资源 ID 是一个整型值&#xff0c;用于唯一标识资源&#xff0c;若需要将资源转换为整型值&#xff0c;通常是指获取资源 ID 或从资源…

vue3搭建实战项目笔记三

vue3搭建实战项目笔记三 3.1.行高偏移问题3.2.谷歌浏览器上不能定位3.2.2 移动端css隐藏滚动条 3.3.获取列表的数据3.3.1 服务器返回十万条数据3.3.2 分页展示数据3.3.2 防止展示数据为空报错 3.4.上拉加载数据3.4.1 加载更多数据3.4.2 监听页面滚动到底部3.4.3 监听滚动的时机…

sqlmap基础命令总结

​注意事项:仅用于授权测试&#xff0c;避免非法使用。 目录 ​一、基础命令 ​二、数据库信息获取 ​三、绕过 WAF/IDS ​四、文件系统与系统命令 ​五、高级功能与优化 ​六、实战示例 ​一、基础命令 ​检测注入点 sqlmap -u "http://target.com/index.php?id1&…

Lucky Chains_Educational Codeforces Round 139

https://codeforces.com/problemset/problem/1766/D 首先有一个性质 gcd(a,b) (a<b) gcd(a,ad) (d>0) gcd(a,ad) gcd(a,d)&#xff0c;这个式子可以这样理解&#xff0c;求a和ad的最大公因数时&#xff0c;a是可以整除这个最大公因数的&#xff0c;要让ad能整除这个…

聚类(Clustering)基础知识3

文章目录 一、聚类的性能评价1、聚类性能评价&#xff08;1&#xff09;聚类性能评价方法&#xff1a; 2、参考模型 (reference model)&#xff08;1&#xff09;数据集&#xff1a;&#xff08;2&#xff09;聚类结果&#xff1a;&#xff08;3&#xff09;参考模型&#xff1…

RK3588使用笔记:debian/ubuntu/麒麟系统下基础功能配置(不定期更新)

一、前言 用于记录使用RK3588这个平台在debian/ubuntu/麒麟系统下的一些功能配置&#xff0c;RK3588只是一个芯片&#xff0c;linux是底层系统&#xff0c;debian/ubuntu/麒麟是桌面文件系统&#xff0c;系统可以运行在无数的芯片上&#xff0c;也都大同小异&#xff0c;本编文…

Linux文件描述符的分配机制与重定向实现:揭开“一切皆文件”的面纱

Linux系列 文章目录 Linux系列前言一、背景介绍二、bash的模拟实现2.1 解析命令行2.2 接受命令行参数2.3 解析指令2.4 执行基础命令2.5 内建命令的处理 三、全部代码总结 前言 在前段时间的学习中&#xff0c;我从Linux基础指令开始分享&#xff0c;一直到上篇的Linux进程程序…

【UE5】摄像机晃动

目录 效果 步骤 一、游戏中晃动视角 二、Sequence中晃动视角 效果 步骤 一、游戏中晃动视角 1. 新建一个蓝图&#xff0c;父类选择“CameraShakeBase” 这里命名为“BP_MyCameraShake” 打开“BP_MyCameraShake”&#xff0c;根晃动模式这里设置为“Perlin噪点摄像机晃…