void UpdateFootPlanting( Transform transform, PlayerFoley playerFoley, float speedSqr, float speedScalar, bool isJumping) { if (isJumping) { if ((_feetPlanted & 8) == 0) { _feetPlanted = 0; } } else { var position = transform.position; var footPlantPosition = new Vector3(position.x, 0f, position.z); float walkStepSqr = footPlanting.walkStepDistance * footPlanting.walkStepDistance; float runStepSqr = footPlanting.runStepDistance * footPlanting.runStepDistance; float stepSqr = (footPlantPosition - _lastFootPlantPosition).sqrMagnitude; float needStepSqr = Mathf.Lerp(walkStepSqr, runStepSqr, speedScalar); _feetPlanted &= ~8; if (_feetPlanted == 0) { _feetPlanted = 1; _lastFootPlantPosition = footPlantPosition; _lastVegetationPosition = footPlantPosition; Vector3 normal; PhysicMaterial physicalMaterial; FindFootPlacement(ref position, out normal, out physicalMaterial); playerFoley.PlayFootstep( transform, position, normal, physicalMaterial, _jumpSpeedScalar, landing: true); } else if (speedSqr <= footPlanting.stopSpeedThreshold * footPlanting.stopSpeedThreshold) { if (_feetPlanted != 2) { _feetPlanted = 2; _lastFootPlantPosition = footPlantPosition; Vector3 normal; PhysicMaterial physicalMaterial; FindFootPlacement(ref position, out normal, out physicalMaterial); playerFoley.PlayFootstep(transform, position, normal, physicalMaterial, speedScalar: 0f); } } else if (stepSqr >= needStepSqr) { _feetPlanted = 1; _lastFootPlantPosition = footPlantPosition; Vector3 normal; PhysicMaterial physicalMaterial; FindFootPlacement(ref position, out normal, out physicalMaterial); playerFoley.PlayFootstep(transform, position, normal, physicalMaterial, speedScalar); } else if (playerFoley.intersectingVegetation) { var vegDistSqr = (footPlantPosition - _lastVegetationPosition).sqrMagnitude; if (vegDistSqr >= needStepSqr * 0.3f) { _lastVegetationPosition = footPlantPosition; Vector3 normal; PhysicMaterial physicalMaterial; FindFootPlacement(ref position, out normal, out physicalMaterial); playerFoley.PlayVegetation(transform, position, speedScalar); } } } }
public void Simulate( CharacterController characterController, PlayerFoley playerFoley, PlayerInput input) { var transform = this.transform; float deltaTime = Time.deltaTime; bool isJumping = !characterController.isGrounded; bool jumpStart = false; if (!isJumping && input.jump) { _jumpingScalar = -jumping.force; jumpStart = true; } else if ((_jumpingScalar += deltaTime * jumping.dampSpeed) >= jumping.gravityFactor) { _jumpingScalar = jumping.gravityFactor; } float frictionFactor = isJumping ? 0.99f : 0.1f; var absMove = new Vector2(Mathf.Abs(input.move.x), Mathf.Abs(input.move.y)); var signMove = new Vector2(Mathf.Sign(input.move.x), Mathf.Sign(input.move.y)); var wantSpeed = Vector2.one; wantSpeed *= Mathf.Lerp(locomotion.walkSpeed, locomotion.runSpeed, input.run); wantSpeed = Vector2.Scale(wantSpeed, signMove); wantSpeed = Vector2.Lerp(_movingSpeed, wantSpeed, isJumping ? 0f : deltaTime * 10f); wantSpeed = Vector2.Scale( wantSpeed, Vector2.Lerp( absMove, new Vector2( Mathf.Approximately(input.move.x, 0f) ? 0f : 1f, Mathf.Approximately(input.move.y, 0f) ? 0f : 1f), input.run)); _movingSpeed = Vector2.Lerp(wantSpeed, wantSpeed * frictionFactor, !isJumping ? 0f : deltaTime); float angularSpeed = 360f * deltaTime * Mathf.Lerp(looking.lookSpeed, looking.runLookSpeed, input.run); float lookX = input.look.x; float lookY = input.look.y * Mathf.Sign(input.move.y); _lookingAngles.x = _lookingAngles.x + lookX * angularSpeed; _lookingAngles.y = _lookingAngles.y + lookY * angularSpeed; _lookingAngles.x = Angles.Unwind( Mathf.Clamp( Angles.ToRelative(_lookingAngles.x), looking.pitchLimitMin, looking.pitchLimitMax)); UpdateLooking(transform, deltaTime); UpdateMoving(transform, deltaTime, characterController); float walkSpeedSqr = locomotion.walkSpeed * locomotion.walkSpeed; float runSpeedSqr = locomotion.runSpeed * locomotion.runSpeed; float speedSqr = _movingSpeed.sqrMagnitude; float speedScalar = (speedSqr - walkSpeedSqr) / (runSpeedSqr - walkSpeedSqr); if (speedScalar < Mathf.Epsilon) { speedScalar = 0f; } int hadFeetPlanted = _feetPlanted; isJumping = !characterController.isGrounded; // check again after moving if (jumpStart) { _jumpSpeedScalar = speedScalar; } UpdateFootPlanting(transform, playerFoley, speedSqr, speedScalar, isJumping); if (jumpStart) { playerFoley.OnJump(); } else if (hadFeetPlanted == 0 && _feetPlanted != 0) { playerFoley.OnLand(); } playerFoley.breathingIntensity = isJumping ? 1f : speedScalar; playerFoley.playerJumping = jumpStart || _feetPlanted == 0; }