/// <summary> /// applies various forces to the camera and weapon springs /// in response to falling impact. /// </summary> protected virtual void OnMessage_FallImpact(float impact) { impact = (float)Mathf.Abs((float)impact * 55.0f); // ('55' is for preset backwards compatibility) float posImpact = (float)impact * PositionKneeling; float rotImpact = (float)impact * RotationKneeling; // smooth step the impacts to make the springs react more subtly // from short falls, and more aggressively from longer falls posImpact = Mathf.SmoothStep(0, 1, posImpact); rotImpact = Mathf.SmoothStep(0, 1, rotImpact); rotImpact = Mathf.SmoothStep(0, 1, rotImpact); // apply impact to camera position spring if (m_PositionSpring != null) { m_PositionSpring.AddSoftForce(Vector3.down * posImpact, PositionKneelingSoftness); } // apply impact to camera rotation spring if (m_RotationSpring != null) { float roll = Random.value > 0.5f ? (rotImpact * 2) : -(rotImpact * 2); m_RotationSpring.AddSoftForce(Vector3.forward * roll, RotationKneelingSoftness); } }
/// <summary> /// applies soft positional and angular force to the weapon /// </summary> public virtual void AddSoftForce(Vector3 positional, Vector3 angular, int frames) { m_PositionSpring.AddSoftForce(positional, frames); m_RotationSpring.AddSoftForce(angular, frames); }
/// <summary> /// pushes the weapon position spring along the 'force' vector /// distributed over 'frames' fixed frames /// </summary> public virtual void AddSoftForce(Vector3 force, int frames) { m_PositionSpring.AddSoftForce(force, frames); }
void FixedUpdate() { // get input if (scrFpsController.getInput == null) { return; } FpsControllerInput input = scrFpsController.getInput(); // lerp toward shouldered or unshouldered position float intensityMultiplier = 1f; if (shouldering) { currentRotation = Quaternion.Lerp(currentRotation, Quaternion.Euler(0f, 0f, 0f), shoulderLerp); currentPosition = Vector3.Lerp(currentPosition, shoulderingPosition, shoulderLerp); if (scrFpsController.grounded) // only have steady weapon if shouldering and grounded { intensityMultiplier = shoulderMovementIntensityMult; } } else { currentRotation = Quaternion.Lerp(currentRotation, originalRotation, unshoulderLerp); currentPosition = Vector3.Lerp(currentPosition, originalPosition, unshoulderLerp); } // movement bob or vertical move inertia float movementBob = 0f; if (scrFpsController.grounded) { // vertical movement Bob movementBob = movementBobIntensity * intensityMultiplier * scrFpsController.GetMoveSpeedPercent() * Mathf.Sin(movementBobTime); movementBobTime += Time.fixedDeltaTime * Mathf.Lerp(movementBobMinFrequency, movementBobMaxFrequency, scrFpsController.GetMoveSpeedPercent()); } else { movementBobTime = 0f; // jump inertia moveInertiaSpring.AddForce(Vector3.down * -scrFpsController.body.velocity.y * moveInertiaMagnitude.y * intensityMultiplier * Time.fixedDeltaTime); } // look inertia lookInertiaSpring.AddSoftForce(new Vector3( input.lookY * -lookInertiaMagnitude.y * intensityMultiplier, // Look Vertical input.lookX * -lookInertiaMagnitude.x * intensityMultiplier, // Look Horizontal input.moveX * -moveBankMagnitude * intensityMultiplier), // Movement Bank lookInertiaDistributeFrames); Vector3 rotatedVelocity = transform.InverseTransformDirection(scrFpsController.body.velocity); // move inertia moveInertiaSpring.AddForce( new Vector3( -rotatedVelocity.x * moveInertiaMagnitude.x * Math.BoolToFloat(!(shouldering && scrFpsController.grounded)), movementBob, -rotatedVelocity.z * moveInertiaMagnitude.z * intensityMultiplier) * Time.fixedDeltaTime); // apply spring transformations transform.localRotation = currentRotation * Quaternion.Euler(lookInertiaSpring.UpdateState()) * Quaternion.Euler(recoilUpwardSpring.UpdateState()); transform.localPosition = currentPosition + moveInertiaSpring.UpdateState() + recoilBackwardSpring.UpdateState(); }