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

本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文件化](#2. FSM的so文件化)

3.土狼时间

4.输入预处理(跳跃)


思维导图

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

玩家具体状态实现

视频介绍:

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

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

1.新输入系统

cs 复制代码
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文件化

cs 复制代码
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.土狼时间

cs 复制代码
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里

cs 复制代码
    public void ResetJumpBuffer()
    {
        StopCoroutine(DoRestJumpBuffer());
        StartCoroutine(DoRestJumpBuffer());
    }
    public IEnumerator DoRestJumpBuffer()
    {

        hasJumpInputBuffer = true;
        yield return new WaitForSeconds(jumpInputBufferTime);
        hasJumpInputBuffer = false;
    }
相关推荐
深海潜水员1 小时前
【Behavior Tree】-- 行为树AI逻辑实现- Unity 游戏引擎实现
游戏·unity·c#
点云登山者8 小时前
登山第二十六梯:单目3D检测一切——一只眼看世界
3d·3d检测·检测一切·单目3d检测
Thomas_YXQ11 小时前
Unity3D游戏内存优化指南
游戏·unity·职场和发展·性能优化·蓝桥杯·游戏引擎·unity3d
xhload3d11 小时前
智慧航天运载体系全生命周期监测 | 图扑数字孪生
物联网·3d·智慧城市·html5·webgl·数字孪生·可视化·工业互联网·三维建模·工控·航空航天·火箭升空·智慧航空·智慧航天·火箭发射·火箭回收
小赖同学啊11 小时前
光伏园区3d系统管理
前端·javascript·3d
chillxiaohan12 小时前
Unity接入Steamworks.NET实现通信功能
unity
枯萎穿心攻击20 小时前
响应式编程入门教程第二节:构建 ObservableProperty<T> — 封装 ReactiveProperty 的高级用法
开发语言·unity·c#·游戏引擎
X_StarX1 天前
【Unity笔记02】订阅事件-自动开门
笔记·学习·unity·游戏引擎·游戏开发·大学生
SDUERPANG1 天前
三维目标检测|Iou3D 代码解读一
人工智能·目标检测·3d
霸王•吕布1 天前
游戏引擎中顶点着色&像素着色
游戏引擎·顶点着色器·像素着色器·顶点颜色·顶点uv·顶点法向