CharacterState previousState, currentState;// 以前状态 当前状态

        void Update()
        {
            float dt         = Time.deltaTime;
            bool  isGrounded = controller.isGrounded;           // 在地面
            bool  landed     = !wasGrounded && isGrounded;      // 登录地面

            // 检测输入
            input.x = Input.GetAxis(XAxis);
            input.y = Input.GetAxis(YAxis);
            bool inputJumpStop   = Input.GetButtonUp(JumpButton);                                       // 跳跃停止
            bool inputJumpStart  = Input.GetButtonDown(JumpButton);                                     // 跳跃开始
            bool doCrouch        = (isGrounded && input.y < -0.5f) || (forceCrouchEndTime > Time.time); // 蹲下
            bool doJumpInterrupt = false;                                                               // 跳跃中断
            bool doJump          = false;                                                               // 跳跃
            bool hardLand        = false;                                                               // 硬着陆

            bool inputAttackStart = Input.GetKey(attackKey);                                            // 攻击开始*
            bool inputAttackStop  = Input.GetKeyUp(attackKey);                                          // 攻击结束*
            bool doAttack         = inputAttackStart;

            //bool doAttack = inputAttackStart || (forceAttackEndTime > Time.time);// 攻击*
            //if (inputAttackStart)
            //{
            //    forceAttackEndTime = Time.time + forceAttackDuration;
            //}

            //** 判定动作变化 **//
            if (landed)                                                   // 如果落到地面上
            {
                if (-velocity.y > forceCrouchVelocity)                    // 如果垂直速度大于 落下速度值
                {
                    hardLand           = true;                            // 硬着陆
                    doCrouch           = true;                            // 做蹲下动作
                    forceCrouchEndTime = Time.time + forceCrouchDuration; // 落下蹲伏动作结束时间
                }
            }

            if (!doCrouch)         // 如果不是做蹲下动作
            {
                if (isGrounded)    // 在地面上
                {
                    if (!doAttack) //*
                    {
                        if (inputJumpStart)
                        {                  // 如果输入跳跃
                            doJump = true; // 做跳跃
                        }
                    }
                }
                else                                                                   // 不在地面上
                {
                    doJumpInterrupt = inputJumpStop && Time.time < minimumJumpEndTime; // 跳跃中断 = 跳跃停止 && 最小跳跃结束时间
                }
            }

            //** 虚拟物理和控制器使用(计算速度)**//
            // 重力加速度
            Vector3 gravityDeltaVelocity = Physics.gravity * gravityScale * dt; // 重力 * 重力缩放 * 这帧时间

            if (doJump)                                                         // 做跳跃动作
            {
                velocity.y         = jumpSpeed;                                 // 竖直速度为跳跃速度
                minimumJumpEndTime = Time.time + minimumJumpDuration;           // 跳跃结束时间
            }
            else if (doJumpInterrupt)                                           // 如果跳跃被中断
            {
                if (velocity.y > 0)
                {
                    velocity.y *= jumpInterruptFactor;                    // 跳跃中断速率
                }
            }

            velocity.x = 0;            // 水平速度为0

            //if (!doCrouch)
            //{// 如果不是做蹲下动作
            if (input.x != 0)
            {                                                                       // 水平轴有输入
                if (doCrouch)                                                       //*
                {                                                                   // 如果不是做蹲下动作
                }
                else if (!isGrounded)                                               //*
                {
                    velocity.x  = Mathf.Abs(input.x) > 0.6f ? runSpeed : walkSpeed; // 跑 || 走
                    velocity.x *= Mathf.Sign(input.x);                              // 左 || 右
                }
                else if (doAttack)                                                  //*
                {
                }
                else
                {
                    velocity.x  = Mathf.Abs(input.x) > 0.6f ? runSpeed : walkSpeed; // 跑 || 走
                    velocity.x *= Mathf.Sign(input.x);                              // 左 || 右
                }
            }
            //}

            if (!isGrounded)
            {     // 如果不在地面上
                if (wasGrounded)
                { // 落到地面时
                    if (velocity.y < 0)
                    {
                        velocity.y = 0;// 竖直速度变为0
                    }
                }
                else
                {                                     // 在空中
                    velocity += gravityDeltaVelocity; // 竖直速度为重力加速度
                }
            }
            controller.Move(velocity * dt);            // 设置人物速度
            wasGrounded = isGrounded;

            //** 确定并存储角色状态 **//
            if (doAttack)  //*
            {
                currentState = CharacterState.Attack;
            }
            else  //*
            {
                if (isGrounded)
                {
                    if (doCrouch)
                    {
                        currentState = CharacterState.Crouch;// 蹲
                    }
                    else
                    {
                        if (input.x == 0)
                        {
                            currentState = CharacterState.Idle;// 闲置
                        }
                        else
                        {
                            currentState = Mathf.Abs(input.x) > 0.6f ? CharacterState.Run : CharacterState.Walk;// 跑 || 走
                        }
                    }
                }
                else
                {
                    currentState = velocity.y > 0 ? CharacterState.Rise : CharacterState.Fall;// 上升 || 下落
                }
            }

            bool stateChanged = previousState != currentState; // 状态是否改变

            previousState = currentState;                      // 状态重置

            // Animation
            // 在此阶段请勿修改字符参数或状态。只是读他们。
            // 检测状态变化,并在变化时进行动画处理。
            if (stateChanged)
            {
                HandleStateChanged();                // 改变动画状态
            }
            if (input.x != 0)
            {
                animationHandle.SetFlip(input.x);                // 设置动画翻转
            }
            // 触发事件(事件调用 播放粒子||声音)
            if (doJump)
            {
                OnJump.Invoke();                // 触发跳跃事件
            }
            if (landed)
            {
                if (hardLand)
                {
                    OnHardLand.Invoke();
                }
                else
                {
                    OnLand.Invoke();
                }
            }
        }
        void Update()
        {
            float dt         = Time.deltaTime;
            bool  isGrounded = controller.isGrounded;
            bool  landed     = !wasGrounded && isGrounded;

            // Dummy input.
            input.x = Input.GetAxis(XAxis);
            input.y = Input.GetAxis(YAxis);
            bool inputJumpStop   = Input.GetButtonUp(JumpButton);
            bool inputJumpStart  = Input.GetButtonDown(JumpButton);
            bool doCrouch        = (isGrounded && input.y < -0.5f) || (forceCrouchEndTime > Time.time);
            bool doJumpInterrupt = false;
            bool doJump          = false;
            bool hardLand        = false;

            if (landed)
            {
                if (-velocity.y > forceCrouchVelocity)
                {
                    hardLand           = true;
                    doCrouch           = true;
                    forceCrouchEndTime = Time.time + forceCrouchDuration;
                }
            }

            if (!doCrouch)
            {
                if (isGrounded)
                {
                    if (inputJumpStart)
                    {
                        doJump = true;
                    }
                }
                else
                {
                    doJumpInterrupt = inputJumpStop && Time.time < minimumJumpEndTime;
                }
            }

            // Dummy physics and controller using UnityEngine.CharacterController.
            Vector3 gravityDeltaVelocity = Physics.gravity * gravityScale * dt;

            if (doJump)
            {
                velocity.y         = jumpSpeed;
                minimumJumpEndTime = Time.time + minimumJumpDuration;
            }
            else if (doJumpInterrupt)
            {
                if (velocity.y > 0)
                {
                    velocity.y *= jumpInterruptFactor;
                }
            }

            velocity.x = 0;
            if (!doCrouch)
            {
                if (input.x != 0)
                {
                    velocity.x  = Mathf.Abs(input.x) > 0.6f ? runSpeed : walkSpeed;
                    velocity.x *= Mathf.Sign(input.x);
                }
            }


            //if (!isGrounded)
            //{
            //    if (wasGrounded)
            //    {
            //        if (velocity.y < 0)
            //            velocity.y = 0;
            //    }
            //    else
            //    {
            //        velocity += gravityDeltaVelocity;
            //    }
            //}
            controller.Move(velocity * dt);
            wasGrounded = isGrounded;

            // Determine and store character state
            if (isGrounded)
            {
                if (doCrouch)
                {
                    currentState = CharacterState.Crouch;
                }
                else
                {
                    if (input.x == 0)
                    {
                        currentState = CharacterState.Idle;
                    }
                    else
                    {
                        currentState = Mathf.Abs(input.x) > 0.6f ? CharacterState.Run : CharacterState.Walk;
                    }
                }
            }
            else
            {
                currentState = velocity.y > 0 ? CharacterState.Rise : CharacterState.Fall;
            }

            bool stateChanged = previousState != currentState;

            previousState = currentState;

            // Animation
            // Do not modify character parameters or state in this phase. Just read them.
            // Detect changes in state, and communicate with animation handle if it changes.
            if (stateChanged)
            {
                HandleStateChanged();
            }

            if (input.x != 0)
            {
                animationHandle.SetFlip(input.x);
            }

            // Fire events.
            if (doJump)
            {
                OnJump.Invoke();
            }
            if (landed)
            {
                if (hardLand)
                {
                    OnHardLand.Invoke();
                }
                else
                {
                    OnLand.Invoke();
                }
            }
        }