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(); } } }