private void Update() { if (_wingsuitActionMap == null) { Debug.LogWarning("No actionmap found"); return; } var wingsuitInput = PollWingsuitInput(_wingsuitActionMap.ActionMap); var prevMouseInput = _mouseWingsuitInput; _mouseWingsuitInput = PollWingsuitMouseInput(_wingsuitActionMap.ActionMap); var mouseWingsuitInput = ApplyWingsuitMouseState(_gameClock.DeltaTime, _mouseGravity, _mouseCancelPower, _mouseBufferStrength, prevMouseInput, _mouseWingsuitInput); _wingsuitInput = wingsuitInput.Merge(mouseWingsuitInput); _cameraInput = PollCameraInput(_wingsuitActionMap.ActionMap); if (_parachuteActionMap == null) { Debug.LogWarning("No parachute actionmap assigned"); return; } _parachuteInput = _parachuteActionMap.V.Input; }
private static CharacterInput ApplyStallPrevention(CharacterInput input, FlightStatistics target, float stallLimitStrength, float rollLimitStrength) { // Disable stall prevention if super-maneuvre inputs are active stallLimitStrength *= 1f - input.Cannonball; rollLimitStrength *= 1f - input.Cannonball; rollLimitStrength *= 1f - Mathf.Max(input.CloseLeftArm, input.CloseRightArm); // Limit both positive and negative pitch motion to keep body from stalling if (input.Pitch > 0f) { float multiplier = 1f - Mathf.InverseLerp(0f, -20f, target.AngleOfAttack) * stallLimitStrength; input.Pitch *= multiplier; } else { float multiplier = 1f - Mathf.InverseLerp(0f, 20f, target.AngleOfAttack) * stallLimitStrength; input.Pitch *= multiplier; } // Limit roll rate if (input.Roll > 0f) { float multiplier = 1f - Mathf.Clamp01((-target.LocalAngularVelocity.y - 1f) * 1f) * rollLimitStrength; input.Roll *= multiplier; } else { float multiplier = 1f - Mathf.Clamp01((target.LocalAngularVelocity.y - 1f) * 1f) * rollLimitStrength; input.Roll *= multiplier; } return(input); }
public void Clear() { _wingsuitInput = CharacterInput.Zero; _localLookRotation = _state == PilotAnimatorState.Wingsuit ? _target.transform.rotation * Quaternion.Euler(-45f, 0f, 0f) : _target.transform.rotation; }
private static CharacterInput ApplyStabilityOverride(CharacterInput input, StabilityOverride stabilityOverride) { input.Pitch = input.Pitch * stabilityOverride.Pitch; input.Roll = input.Roll * stabilityOverride.Roll; input.Yaw = input.Yaw * stabilityOverride.Yaw; return(input); }
public CharacterInput ApplyStabilization(CharacterInput input, FlightStatistics target, float deltaTime) { input = ApplyStallPrevention(input, target, _userConfig.StallLimiterStrength, _userConfig.RollLimiterStrength); var stabilityInput = CharacterInput.Zero; // Update gyroscopic stability var error = GetGyroError(deltaTime, target, _lastGyroError, _c.ErrorSmoothingSpeed); _lastGyroError = error; var pids = GetGyroPidOutputs(error); var gyroCorrection = PidOutputToCharacterInput(pids); gyroCorrection = CharacterInput.Lerp(_lastGyroCorrection, gyroCorrection, _c.StabilityCorrectionSpeed * deltaTime); _lastGyroCorrection = gyroCorrection; stabilityInput += gyroCorrection; // Apply stability overrides (Player input cancels out stabilization effects) var stabilityOverride = GetStabilityOverrides(input, _c.MaxStabilityOverride); stabilityInput = ApplyStabilityOverride(stabilityInput, stabilityOverride); input += stabilityInput; // Apply speed scaling to summed inputs float normalizedSpeed = Mathf.Clamp01(target.RelativeVelocity.magnitude / _c.MaxSpeed); return(ApplySpeedScaling(input, normalizedSpeed, _userConfig.InputSpeedScaling, 1.5f)); }
private static StabilityOverride GetStabilityOverrides(CharacterInput playerInput, float maxOverrideFactor) { Func <float, float, float> overrideFactor = (input, maxOverride) => 1f - Mathf.Abs(input) * maxOverride; //Todo: Cache this func? return(new StabilityOverride { Pitch = overrideFactor(playerInput.Pitch, maxOverrideFactor), Roll = overrideFactor(playerInput.Roll, maxOverrideFactor), Yaw = overrideFactor(playerInput.Yaw, maxOverrideFactor), }); }
public CharacterInput Merge(CharacterInput c) { return(new CharacterInput { Pitch = Adapters.MergeAxes(Pitch, c.Pitch), Roll = Adapters.MergeAxes(Roll, c.Roll), Yaw = Adapters.MergeAxes(Yaw, c.Yaw), Cannonball = Adapters.MergeAxes(Cannonball, c.Cannonball), CloseLeftArm = Adapters.MergeAxes(CloseLeftArm, c.CloseLeftArm), CloseRightArm = Adapters.MergeAxes(CloseRightArm, c.CloseRightArm), }); }
public static CharacterInput Lerp(CharacterInput c1, CharacterInput c2, float lerp) { return(new CharacterInput() { Pitch = Mathf.Lerp(c1.Pitch, c2.Pitch, lerp), Roll = Mathf.Lerp(c1.Roll, c2.Roll, lerp), Yaw = Mathf.Lerp(c1.Yaw, c2.Yaw, lerp), Cannonball = Mathf.Lerp(c1.Cannonball, c2.Cannonball, lerp), CloseLeftArm = Mathf.Lerp(c1.CloseLeftArm, c2.CloseLeftArm, lerp), CloseRightArm = Mathf.Lerp(c1.CloseRightArm, c2.CloseRightArm, lerp), }); }
private static CharacterInput ApplySpeedScaling(CharacterInput input, float normalizedAirspeed, float speedScaling, float speedScalingPower) { float scale = Mathf.Max(0.2f, 1f - Mathf.Pow(normalizedAirspeed, speedScalingPower) * speedScaling); return(new CharacterInput { Pitch = input.Pitch * scale, Roll = input.Roll * scale, Yaw = input.Yaw * scale, Cannonball = input.Cannonball, CloseLeftArm = input.CloseLeftArm, CloseRightArm = input.CloseRightArm }); }
public void Clear() { _wingsuitInput = CharacterInput.Zero; _parachuteInput = ParachuteInput.Zero; }
private static CharacterInput ApplyWingsuitMouseState(float deltaTime, float gravity, float cancelPower, float inputBufferStrength, CharacterInput prevInput, CharacterInput input) { /* Todo: * * Mouse control should be mode-less. This click 'n hold business is too complex, but simple input = output mapping is not good enough either * What we certainly want to avoid: multiple mouse drags for longer maneuvers. * * We want to make mouse input 'sticky' in some situations, but not in others. The stickiness should be fluid, and automatic. * By sticky, I mean we want some input to stay active over time. * We might be able to use mouse input magnitude to determine how muc */ var adjustedInput = input; //Debug.Log(input.Pitch); adjustedInput.Pitch = prevInput.Pitch + input.Pitch * inputBufferStrength; adjustedInput.Roll = prevInput.Roll + input.Roll * inputBufferStrength; adjustedInput.Pitch = Mathf.Lerp(adjustedInput.Pitch, 0, deltaTime * gravity); adjustedInput.Roll = Mathf.Lerp(adjustedInput.Roll, 0, deltaTime * gravity); if (Mathf.Abs(input.Pitch) > 0f) { adjustedInput.Pitch = Mathf.Sign(input.Pitch) != Mathf.Sign(prevInput.Pitch) ? Mathf.Lerp(adjustedInput.Pitch, input.Pitch, cancelPower * deltaTime) : adjustedInput.Pitch; } if (Mathf.Abs(input.Roll) > 0f) { adjustedInput.Roll = Mathf.Sign(input.Roll) != Mathf.Sign(prevInput.Roll) ? Mathf.Lerp(adjustedInput.Roll, input.Roll, cancelPower * deltaTime) : adjustedInput.Roll; } adjustedInput.Pitch = Mathf.Clamp(adjustedInput.Pitch, -1f, 1f); adjustedInput.Roll = Mathf.Clamp(adjustedInput.Roll, -1f, 1f); return(adjustedInput); }
public void SetInput(CharacterInput wingsuitInput, ParachuteInput parachuteInput, CameraInput cameraInput) { _wingsuitInput = wingsuitInput; _parachuteInput = parachuteInput; _cameraInput = cameraInput; }
public CharacterInput SmoothInput(CharacterInput input, float deltaTime) { _smoothPlayerInput = CharacterInput.Lerp(_smoothPlayerInput, input, _c.InputSmoothingSpeed * deltaTime); return(_smoothPlayerInput); }
private void AnimateWingsuit(CharacterInput input, CharacterMuscleLimits limits, CharacterParts parts) { PlayerPose.Lerp(ref _currentPose, _defaultPose, _curledPose, input.Cannonball); float normalizedSpeed = Mathf.Clamp01(_target.RelativeVelocity.magnitude / _wingsuitStabilizerConfig.MaxSpeed); input.CloseLeftArm += Mathf.Pow(normalizedSpeed, 1.5f) * 0.25f; input.CloseRightArm += Mathf.Pow(normalizedSpeed, 1.5f) * 0.25f; float pitchUp = Mathf.Min(0f, input.Pitch); float pitchDown = Mathf.Min(0f, -input.Pitch); CharacterMuscleOutput o = new CharacterMuscleOutput(); /* Transform user input into joint angle modifications. (still in unit values) */ o.ShoulderLPitch = input.Pitch + input.Roll - input.CloseLeftArm; o.ShoulderRPitch = input.Pitch - input.Roll - input.CloseRightArm; o.ArmLUpperPitch = input.Roll * 0.3f + pitchDown * 0f - input.CloseLeftArm * 0.5f; o.ArmRUpperPitch = -input.Roll * 0.3f + pitchDown * 0f - input.CloseRightArm * 0.5f; o.ArmLUpperRoll = -input.Pitch; o.ArmRUpperRoll = input.Pitch; o.ArmLLowerPitch = -input.Pitch * 1f + -input.Roll * 0.5f + input.CloseLeftArm * 0.0f; o.ArmRLowerPitch = -input.Pitch * 1f + input.Roll * 0.5f + input.CloseRightArm * 0.0f; o.ArmLClose = -input.CloseLeftArm * 1f + pitchDown * 1f + input.Roll * (input.Roll < 0f ? 1f : 0f); o.ArmRClose = input.CloseRightArm * 1f - pitchDown * 1f + input.Roll * (input.Roll > 0f ? 1f : 0f); o.LegLUpperPitch = pitchUp * 1.0f + Mathf.Pow(pitchDown, 2f) * 0.5f + input.Yaw * 0.25f; o.LegRUpperPitch = pitchUp * 1.0f + Mathf.Pow(pitchDown, 2f) * 0.5f - input.Yaw * 0.25f; o.LegLUpperRoll = input.Roll; o.LegRUpperRoll = input.Roll; o.LegLLowerPitch = pitchUp * 1f + Mathf.Pow(pitchDown, 2f) + input.Yaw * 1f; o.LegRLowerPitch = pitchUp * 1f + Mathf.Pow(pitchDown, 2f) - input.Yaw * 1f; o.TorsoPitch = pitchUp * 0.5f; o.TorsoRoll = input.Roll * 1f + input.Yaw * 1f; o.TorsoYaw = input.Yaw * 0.5f; CharacterMuscleOutput.Clamp(ref o); CharacterMuscleOutput.ScaleToLimits(ref o, limits); CharacterMuscleOutput.ApplyPose(ref o, _currentPose); /* Apply a specific stability effect to just the arms (Todo: move this elsewhere, make configurable) */ float armUpperPitchHeadingStability = 10f * Mathf.InverseLerp(15f, -5f, _target.AngleOfAttack); o.ArmLUpperPitch += armUpperPitchHeadingStability; o.ArmRUpperPitch += armUpperPitchHeadingStability; float armLowerPitchHeadingStability = 15f * Mathf.InverseLerp(20f, -5f, _target.AngleOfAttack); o.ArmLLowerPitch += armLowerPitchHeadingStability; o.ArmRLowerPitch += armLowerPitchHeadingStability; /* Apply user-configured pitch attitude offset */ o.TorsoPitch += limits.PitchAttitudeTorsoMax * _userConfig.PitchAttitude; o.LegLUpperPitch += limits.PitchAttitudeLegsMax * _userConfig.PitchAttitude; o.LegRUpperPitch += limits.PitchAttitudeLegsMax * _userConfig.PitchAttitude; /* Send new targets to all the joints */ CharacterMuscleOutput.Output(ref o, parts); }