override public void LandOnGround() { // Land on ground var block = world.GetBlock(position); if (!WorldUtils.IsCapBlock(block)) { block = world.GetBlock(footPosition(position)); } float d = 0; float fallSpeed = -velocity.y; if (fallSpeed > data.fallDamageSpeed) { d = (fallSpeed - data.fallDamageSpeed) / data.fallDamageSpeed * gameMode.GetTerrainData(position).fallDamage *data.maxHealth; if (d > 0) { Damage(d, PawnData.DamageType.Falling, true); Stun((float)d); } } gameMode.CreateAudioEvent(this, fallSpeed * data.fallSpeedLoudness); OnLand?.Invoke(d); }
private void FixedUpdate() { transform.Translate(new Vector3(0, (currentSpeed < 0 ? currentSpeed * fallingMultiplier : currentSpeed) * Time.fixedDeltaTime, 0)); if (!isJumping) { return; } if (transform.position.y < losePosition) { onJump.Invoke(false); loseEvent.Invoke(); return; } for (int i = 0; i < columns.columns.Count; i++) { Transform column = columns.columns[i]; if (column.position.y <= transform.position.y && column.position.y + positionOddY >= transform.position.y) { if (column.position.x - positionOddX <= transform.position.x && column.position.x + positionOddX >= transform.position.x) { currentSpeed = 0; isRecovering = true; isJumping = false; landingPosition = transform.position; nextColumnIndex = i; onJump.Invoke(false); onLand.Invoke(); currentColumn = column; currentColumnIndex = i; nextColumnIndex = nextColumnIndex + 1 >= columns.columns.Count ? 0 : nextColumnIndex + 1; return; } } } if (columns.columns[nextColumnIndex].position.x - transform.position.x >= 0) { if (transform.position.y < columns.columns[nextColumnIndex].position.y) { if (columns.columns[nextColumnIndex].position.x - transform.position.x <= faceplantDistance) { onJump.Invoke(false); } } } else { nextColumnIndex = nextColumnIndex + 1 >= columns.columns.Count ? 0 : nextColumnIndex + 1; print("current " + currentColumnIndex + ", next" + nextColumnIndex); } currentSpeed -= fallSpeed * Time.fixedDeltaTime; }
//플레이어가 떨어지는 중이 아니라면 //지상에 있는 상태로 변경 private IEnumerator PlayOnGroundAnimation() { IsDroping = true; while (transform.position.y > 2f) { yield return(null); } myAnimator.SetTrigger("IsOnGround"); IsDroping = false; OnLand?.Invoke(this, EventArgs.Empty); yield break; }
private void OnTriggerEnter2D(Collider2D collision) { if (!collision.isTrigger && collision.gameObject != gameObject) { if (!isStand && timerLeaveLand > 0.12f) { // 着陆 OnLand?.Invoke(); } isStand = true; isJump = false; isForceJump = false; isSecondJump = false; } }
void InitializeDelegates() { characterGroundedCheck.onLeaveOverLapCircleDelegate += () => { isGrounded = false; ChangeState(2); }; characterGroundedCheck.onEnterOverlapCircleDelegate += (collider2D) => { OnLand?.Invoke(); isGrounded = true; }; characterControl.axesDelegate += (vec2) => { movementAxes = vec2; }; characterLadderClimb.climbingLadderDelegate += climbing => isClimbing = climbing; }
/// <summary> /// Handles the basic movement, like walking and jumping. /// </summary> protected virtual void BasicMovement(float deltaTime) { // Only run if air jump is enabled. if (airJump) { // If the current air time is above 0, decrease it. if (currentAirTime > 0) { currentAirTime -= deltaTime; } // If current air time is less than or equal to 0, the player should no longer jump. if (currentAirTime <= 0) { shouldJump = false; } } // If the player isn't grounded, handle gravity. // Else apply the ground stick so the player sticks to the ground. if (!isGrounded) { // If the player was just grounded, set the jump position. // The player probably just jumped or started falling. if (previouslyGrounded) { // Set the jump position to the current player transform. jumpPosition = PlayerTransform.position; if (!isJumping) { currentJumps++; } } // When the step offset is above 0 the player can get stuck on the ceiling. Try and prevent that. if (CharacterController.stepOffset > 0) { // If the player's head is touching the ceiling, move the player down so they don't // get stuck on the ceiling. if ((CharacterController.collisionFlags & CollisionFlags.Above) != 0) { moveDirection.y = -5f; isJumping = false; isFalling = true; } } // The player was previously not grounded. previouslyGrounded = false; // If the player isn't grounded and not jumping, it is probably falling. // So set falling to true and reset the Y move direction. if (!isFalling && !isJumping) { currentAirTime = airJumpTime; isFalling = true; moveDirection.y = 0; } // Apply gravity to the Y axis. moveDirection.y -= gravity * deltaTime; } else { // If the player is grounded now and wasn't previously, the player just landed. if (!previouslyGrounded) { // Calculate the fall height. float fallHeight = jumpPosition.y - PlayerTransform.position.y; // Reset the air jumps. currentJumps = -1; // Invoke the OnPlayerLand event. #if NET_4_6 || (UNITY_2018_3_OR_NEWER && !NET_LEGACY) OnLand?.Invoke(fallHeight); #else if (OnLand != null) { OnLand.Invoke(fallHeight); } #endif } // The player is on the ground so it is not falling or jumping. isFalling = false; isJumping = false; // The player was previously grounded. previouslyGrounded = true; // If ground stick is enabled and the player isn't jumping, apply the ground stick effect. moveDirection.y = enableGroundStick ? -groundStick : 0; } // Make sure the player is moving in the right direction. HandleMovementDirection(); // Tell the player it should jump if the jump button is pressed, the player can jump, and if the player can move around. if (canJump && canMoveAround && GetButtonDown(input_Jump)) { // Check if the player should jump. shouldJump = ShouldJump(); } // If the player should jump, jump! if (shouldJump) { Jump(); } }
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(); } } }
public void Land() { OnLand?.Invoke(); }
private void OnTriggerEnter2D(Collider2D collision) { isGrounded = true; 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(); } } }
/* * private void CheckJump() * { * // we're not touching the ground layer, don't bother with jump * if (!isGrounded) * { * return; * } * * if (CrossPlatformInputManager.GetButtonDown("Jump")) * { * Vector2 jumpVelocityToAdd = new Vector2(0f, jumpSpeed); * rigidbody2D.velocity += jumpVelocityToAdd; * OnJump.Invoke(); * } * } */ void Land() { OnLand.Invoke(); }