private float getFixedVsVelocityFactor(float speedCoeff) { // If the car isn't moving, default to looking forwards if (veh.Velocity.Magnitude() < nearlySttopedSpeed) { return(0f); } else { // for bikes, always look at velocity if (isCycleOrByke) { return(1f); } // if veh is in air, look at is velocity if (veh.IsInAir || veh.CurrentGear == 0) { return(1f); } else // if is on the ground. fit camera (mostly) behind vehicle (for better drift control) { // Different factors for low/high speed return(MathR.Lerp(velocityInfluenceLowSpeed, velocityInfluence, MathR.Clamp(speedCoeff / lowSpeedLimit, 0f, 1f))); } } }
private void updateCameraCommon() { smoothIsInAir = MathR.Lerp(smoothIsInAir, veh.IsInAir || veh.IsUpsideDown ? 1f : 0f, 2f * getDeltaTime()); smoothIsRearGear = MathR.Lerp(smoothIsRearGear, veh.CurrentGear == 0 ? 1f : 0f, 1.3f * getDeltaTime()); //speedCoeff = MathR.Max(veh.Speed, veh.Velocity.Magnitude() * 0.045454f); //pointAt = veh.Position + fullHeightOffset + (veh.ForwardVector * computeLookFrontOffset(veh, speedCoeff, smoothIsInAir)); }
private void updateCameraCommon() { speedCoeff = MathR.Max(veh.Speed, veh.Velocity.Magnitude() * 0.045454f); pointAt = veh.Position + fullHeightOffset + (veh.ForwardVector * computeLookFrontOffset(speedCoeff, script.smoothIsInAir)); fullLongitudeOffset = (distanceOffset + currentVehicleLongitudeOffset) /* + vehDummyOffset*/ + towedVehicleLongitude; finalDummyOffset = MathR.Lerp(vehDummyOffset, vehDummyOffsetHighSpeed, speedCoeff / (maxHighSpeed * 1.6f)); // no offset if car is in the air finalDummyOffset = MathR.Lerp(finalDummyOffset, 0f, script.smoothIsInAir); currentDistanceIncrement = 0f; if (increaseDistanceAtHighSpeed) { var factor = veh.Speed / maxHighSpeed; currentDistanceIncrement = MathR.Lerp(0f, maxHighSpeedDistanceIncrement, Easing.EaseOut(factor, useEasingForCamDistance ? EasingType.Cubic : EasingType.Linear)); } if (accelerationAffectsCamDistance) { var factor = getVehicleAcceleration() / (maxHighSpeed * 10f); currentDistanceIncrement += MathR.Lerp(0f, accelerationCamDistanceMultiplier, Easing.EaseOut(factor, useEasingForCamDistance ? EasingType.Quadratic : EasingType.Linear)); } }
private float computeLookFrontOffset(float speedCoeff, float smoothIsInAir) { var speed = speedCoeff; var factor = MathR.InverseLerp(lookLowSpeedStart, lookLowSpeedEnd, speedCoeff); var res = MathR.Lerp(lookFrontOffsetLowSpeed, lookFrontOffset, factor); // No offset while in air res = MathR.Lerp(res, 0f, script.smoothIsInAir); return(res); }
public void updateCameraCommon() { fullLongitudeOffset = distanceOffset + currentVehicleLongitudeOffset + towedVehicleLongitude; currentDistanceIncrement = 0f; if (increaseDistanceAtHighSpeed) { var factor = veh.Speed / maxHighSpeed; currentDistanceIncrement = MathR.Lerp(0f, maxHighSpeedDistanceIncrement, Easing.EaseOut(factor, useEasingForCamDistance ? EasingType.Cubic : EasingType.Linear)); } if (accelerationAffectsCamDistance) { var factor = getVehicleAcceleration() / (maxHighSpeed * 10f); currentDistanceIncrement += MathR.Lerp(0f, accelerationCamDistanceMultiplier, Easing.EaseOut(factor, useEasingForCamDistance ? EasingType.Quadratic : EasingType.Linear)); } }
public override void updateCamera() { base.updateCamera(); updateCameraCommon(); var camExtraHeightV3 = Vector3.WorldUp * extraCamHeight; var posCenter = veh.Position + fullHeightOffset; float rotSpeed = rotationSpeed; if(useVariableRotSpeed) { var desiredRootSpeed = MathR.SmoothStep(minRotSpeed, maxRotSpeed, MathR.Clamp01(AngleInDeg(veh.ForwardVector, veh.Velocity) / 90)); currentRootSpeed = MathR.Lerp(currentRootSpeed, desiredRootSpeed, 2f * Time.getDeltaTime()); } if (veh.Speed > 1f) { //velQuat = MathR.LookRotation(veh.Velocity, Vector3.WorldUp); velocityQuat = MathR.XLookRotation(smoothVelocity); } Quaternion vehQuat; if(isCycleOrByke) { // Bykes / cycles (avoid unwanted cam rotations during wheelies/stoppies) if (veh.Speed < 3f) { if(veh.IsOnAllWheels) vehQuat = getRotationFromAverageWheelPosBike(); else vehQuat = getSurfaceNormalRotation(); // Possibly unperformant (using it only for wheelie/stoppie al low speeds) } else vehQuat = velocityQuat; } else // cars { if(avoidCameraBouncinessCar && veh.IsOnAllWheels) { vehQuat = getRotationFromAverageWheelPosCar(); // Avoid camera movements caused by car suspension movement (wheels are on the floor) } else { vehQuat = veh.Quaternion; } } //smoothQuat = MathR.QuatNlerp(smoothQuat, veh.Quaternion, MathR.Clamp01(rotationSpeed * Time.getDeltaTime())); smoothQuat = Quaternion.SlerpUnclamped(smoothQuat, vehQuat, rotationSpeed * Time.getDeltaTime()); smoothVelQuat = Quaternion.Lerp(smoothVelQuat, velocityQuat, 2f * Time.getDeltaTime()); finalQuat = Quaternion.Lerp(smoothQuat, velocityQuat, script.smoothIsInAir); float finalDistMult = 1f; if (veh.Speed > 0.15f) { // TODO Optimize? finalDistMult = Vector3.Angle(finalQuat * Vector3.RelativeFront, veh.Velocity) / 180f; finalDistMult = MathR.Lerp(1f, -1f, finalDistMult); } if(script.isMouseLooking) { finalQuat = Quaternion.Lerp(finalQuat, getFreelookQuaternion(), script.smoothIsFreeLooking); } targetCamera.Position = posCenter + camExtraHeightV3 + (finalQuat * Vector3.RelativeBack * (fullLongitudeOffset + ( currentDistanceIncrement * finalDistMult ))); var pointAt = posCenter - finalQuat * Vector3.RelativeBack * (currentDistanceIncrement + 2f); targetCamera.PointAt(pointAt); }
private Transform UpdateCameraRear() { // smooth out current rotation and position currentRotation = MathR.EulerNlerp(currentRotation, rearCamCurrentTransform.quaternion, (responsivenessMultiplier * generalMovementSpeed) * Time.getDeltaTime()); currentPos = Vector3.Lerp(currentPos, rearCamCurrentTransform.position, MathR.Clamp01((responsivenessMultiplier * generalMovementSpeed) * Time.getDeltaTime())); Quaternion look; var wantedPos = veh.Position + (veh.ForwardVector * finalDummyOffset); // If veh has towed vehicle, increase camera distance by towed vehicle longitude // should camera be attached to vehicle's back or back his velocity var fixedVsVelocity = getFixedVsVelocityFactor(speedCoeff); Quaternion vehQuat = veh.Quaternion; // Compute camera position rear the vechicle var wantedPosFixed = wantedPos - veh.Quaternion * Vector3.RelativeFront * fullLongitudeOffset; // smooth out velocity // Compute camera postition rear the direction of the vehcle if (speedCoeff >= stoppedSpeed) { wantedPosVelocity = wantedPos + MathR.QuaternionLookRotation(smoothVelocity) * Vector3.RelativeBottom * fullLongitudeOffset; } // Smooth factor between two above cam positions smoothFixedVsVelocity = MathR.Lerp(smoothFixedVsVelocity, fixedVsVelocity, (fixedVsVelocitySpeed) * Time.getDeltaTime()); if (!isCycleOrByke) { tempSmoothVsVl = MathR.Lerp(tempSmoothVsVl, MathR.Clamp(speedCoeff * 0.4347826f, 0.025f, 1f), (fixedVsVelocitySpeed * 0.05f)); smoothFixedVsVelocity = MathR.Lerp(0f, smoothFixedVsVelocity, tempSmoothVsVl); } wantedPos = Vector3.Lerp(wantedPosFixed, wantedPosVelocity, MathR.Clamp01(smoothFixedVsVelocity)); //currentPos = Vector3.Lerp(currentPos, wantedPos, Mathr.Clamp01((responsivenessMultiplier * cameraStickiness) * Time.getDeltaTime())); currentPos = Vector3.Lerp(currentPos, wantedPos, MathR.Clamp01((responsivenessMultiplier * cameraStickiness) * Time.getDeltaTime())); //rearCamCurrentTransform.position = currentPos; targetCamera.PointAt(pointAt); look = Quaternion.Euler(targetCamera.Rotation); // Rotate the camera towards the velocity vector. var finalCamRotationSpeed = MathR.Lerp(cameraRotationSpeedLowSpeed, cameraRotationSpeed, ((speedCoeff / lowSpeedLimit) * 1.32f) * Time.getDeltaTime() * 51f); look = MathR.EulerNlerp(currentRotation, look, (1.8f * finalCamRotationSpeed) * Time.getDeltaTime()); // Fix stuttering (mantain camera distance fixed in local space) Transform fixedDistanceTr = new Transform(currentPos + fullHeightOffset + (Vector3.WorldUp * extraCamHeight), Quaternion.Identity); fixedDistanceTr.PointAt(pointAt); Quaternion finalQuat = fixedDistanceTr.quaternion; if (script.isMouseLooking) { finalQuat = Quaternion.Lerp(finalQuat, getFreelookQuaternion(), script.smoothIsFreeLooking); } fixedDistanceTr.position = veh.Position + fullHeightOffset + (Vector3.WorldUp * extraCamHeight) + (finalQuat * Vector3.RelativeBack * (fullLongitudeOffset + currentDistanceIncrement)); //fixedDistanceTr.position = fixedDistanceTr.position + fullHeightOffset; var transform = new Transform(); transform.position = fixedDistanceTr.position; //transform.position = currentPos + fullHeightOffset; transform.rotation = look.ToEulerAngles(); transform.quaternion = look; rearCamCurrentTransform = transform; return(transform); }