/// <summary> /// A method for applying a collection of modifications to some stats. /// </summary> /// <param name="modifiers">A collection of modifiers to the kart stats to be applied in order.</param> /// <param name="startingStats">The initial stats to be modified.</param> /// <param name="modifiedStats">The result of modifying the starting stats.</param> public static void GetModifiedStats(List <IKartModifier> modifiers, KartStats startingStats, ref KartStats modifiedStats) { modifiedStats.acceleration = startingStats.acceleration; modifiedStats.braking = startingStats.braking; modifiedStats.coastingDrag = startingStats.coastingDrag; modifiedStats.gravity = startingStats.gravity; modifiedStats.grip = startingStats.grip; modifiedStats.reverseAcceleration = startingStats.reverseAcceleration; modifiedStats.reverseSpeed = startingStats.reverseSpeed; modifiedStats.topSpeed = startingStats.topSpeed; modifiedStats.turnSpeed = startingStats.turnSpeed; modifiedStats.weight = startingStats.weight; for (int i = 0; i < modifiers.Count; i++) { modifiedStats.acceleration = modifiers[i].ModifyAcceleration(modifiedStats.acceleration); modifiedStats.braking = modifiers[i].ModifyBraking(modifiedStats.braking); modifiedStats.coastingDrag = modifiers[i].ModifyCoastingDrag(modifiedStats.coastingDrag); modifiedStats.gravity = modifiers[i].ModifyGravity(modifiedStats.gravity); modifiedStats.grip = modifiers[i].ModifyGrip(modifiedStats.grip); modifiedStats.reverseAcceleration = modifiers[i].ModifyReverseAcceleration(modifiedStats.reverseAcceleration); modifiedStats.reverseSpeed = modifiers[i].ModifyReverseSpeed(modifiedStats.reverseSpeed); modifiedStats.topSpeed = modifiers[i].ModifyTopSpeed(modifiedStats.topSpeed); modifiedStats.turnSpeed = modifiers[i].ModifyTurnSpeed(modifiedStats.turnSpeed); modifiedStats.weight = modifiers[i].ModifyWeight(modifiedStats.weight); } }
void FixedUpdate() { if (Mathf.Approximately(Time.timeScale, 0f)) { return; } if (m_RepositionPositionDelta.sqrMagnitude > float.Epsilon || m_RepositionRotationDelta != Quaternion.identity) { m_Rigidbody.MovePosition(m_Rigidbody.position + m_RepositionPositionDelta); m_Rigidbody.MoveRotation(m_RepositionRotationDelta * m_Rigidbody.rotation); m_RepositionPositionDelta = Vector3.zero; m_RepositionRotationDelta = Quaternion.identity; return; } m_RigidbodyPosition = m_Rigidbody.position; KartStats.GetModifiedStats(m_CurrentModifiers, defaultStats, ref m_ModifiedStats); ClearTempModifiers(); Quaternion rotationStream = m_Rigidbody.rotation; float deltaTime = Time.deltaTime; m_CurrentGroundInfo = CheckForGround(deltaTime, rotationStream, Vector3.zero); if (m_CurrentGroundInfo.isGrounded && !m_IsGrounded) { OnBecomeGrounded.Invoke(); } if (!m_CurrentGroundInfo.isGrounded && m_IsGrounded) { OnBecomeAirborne.Invoke(); } m_IsGrounded = m_CurrentGroundInfo.isGrounded; GroundInfo nextGroundInfo = CheckForGround(deltaTime, rotationStream, m_Velocity * deltaTime); GroundNormal(deltaTime, ref rotationStream, m_CurrentGroundInfo, nextGroundInfo); TurnKart(deltaTime, ref rotationStream); StartDrift(m_CurrentGroundInfo, nextGroundInfo, rotationStream); StopDrift(deltaTime); CalculateDrivingVelocity(deltaTime, m_CurrentGroundInfo, rotationStream); Vector3 penetrationOffset = SolvePenetration(rotationStream); penetrationOffset = ProcessVelocityCollisions(deltaTime, rotationStream, penetrationOffset); rotationStream = Quaternion.RotateTowards(m_Rigidbody.rotation, rotationStream, rotationCorrectionSpeed * deltaTime); AdjustVelocityByPenetrationOffset(deltaTime, ref penetrationOffset); m_Rigidbody.MoveRotation(rotationStream); m_Rigidbody.MovePosition(m_RigidbodyPosition + m_Movement); }
void Update() { if (m_movement.IsControlled()) { carStats = m_movement.GetModifiedStats(); shortestDistance = Vector3.Distance(targetPosition, kart.position); deltaTime = Time.deltaTime; for (int steering = -1; steering < 2; steering++) { for (int acceleration = -1; acceleration < 2; acceleration++) { otherVector = LocalVelocity(deltaTime, kart.rotation, steering, acceleration, kart.velocity, carStats); otherDistance = Vector3.Distance(targetPosition, kart.position + otherVector); if (otherDistance < shortestDistance) { shortestDistance = otherDistance; m_Steering = steering; m_Acceleration = acceleration; } } } //If the car is driving backwards then turn around if (DrivingBackwards(deltaTime, kart.rotation, m_Steering, m_Acceleration, kart.velocity, carStats)) { otherVector = LocalVelocity(deltaTime, kart.rotation, 1f, -1f, kart.velocity, carStats); shortestDistance = Vector3.Distance(targetPosition, kart.position + otherVector); if (shortestDistance < Vector3.Distance(targetPosition, kart.position + LocalVelocity(deltaTime, kart.rotation, -1f, -1f, kart.velocity, carStats))) { m_Steering = 1f; } else { m_Steering = -1f; } m_Acceleration = 1f; } //give a small boost each time a waypoint is hit if (justHitWayPoint) { justHitWayPoint = false; m_Acceleration *= 2f; } } }
public void AnimateSuspension(Vector3 suspensionNeutralPos, KartStats stats, Transform suspensionBody) { var suspensionTargetPos = suspensionNeutralPos; var bodyRot = transform.rotation.eulerAngles; var maxXTilt = stats.Suspension * 45; var closestNeutralRot = Mathf.Abs(360 - bodyRot.x) < Mathf.Abs(bodyRot.x) ? 360 : 0; var xTilt = Mathf.DeltaAngle(closestNeutralRot, bodyRot.x); var suspensionT = Mathf.InverseLerp(0, maxXTilt, xTilt); suspensionT *= suspensionT; bodyRot.x = Mathf.Lerp(closestNeutralRot, bodyRot.x, suspensionT); var suspensionTargetRot = Quaternion.Inverse(suspensionBody.transform.rotation) * Quaternion.Euler(bodyRot); suspensionBody.transform.localPosition = Vector3.Lerp(suspensionBody.transform.localPosition, suspensionTargetPos, Time.deltaTime * 5f); suspensionBody.transform.localRotation = Quaternion.Slerp(suspensionBody.transform.localRotation, suspensionTargetRot, Time.deltaTime * 5f); }
/// <summary> /// Initialises the KartStats to a default value of 1. /// </summary> public MultiplicativeKartModifier() { modifiers = new KartStats(1f); }
/// <summary> /// Initialises the KartStats to a default value of 0. /// </summary> public AddativeKartModifier() { modifiers = new KartStats(0f); }
void FixedUpdate() { if (Mathf.Approximately(Time.timeScale, 0f)) { return; } if (m_RepositionPositionDelta.sqrMagnitude > float.Epsilon || m_RepositionRotationDelta != Quaternion.identity) { m_Rigidbody.MovePosition(m_Rigidbody.position + m_RepositionPositionDelta); m_Rigidbody.MoveRotation(m_RepositionRotationDelta * m_Rigidbody.rotation); m_RepositionPositionDelta = Vector3.zero; m_RepositionRotationDelta = Quaternion.identity; return; } m_RigidbodyPosition = m_Rigidbody.position; KartStats.GetModifiedStats(m_CurrentModifiers, defaultStats, ref m_ModifiedStats); ClearTempModifiers(); Quaternion rotationStream = m_Rigidbody.rotation; float deltaTime = Time.deltaTime; //Para MRU if (m_Racer.GetLapTime() > 1 && m_ModifiedStats.acceleration == 5) { m_ModifiedStats.acceleration = 0f; //Debug.Log(deltaTime); } ; // Para MRUV if (m_Racer.GetLapTime() > 0f && m_Racer.GetLapTime() < 0.5f && m_ModifiedStats.acceleration == 1) { if (ace) { acelerar_mruv += 1.5f; ace = false; } m_ModifiedStats.acceleration = acelerar_mruv; //Debug.Log(deltaTime); } ; if (m_Racer.GetLapTime() > 0.5f) { ace = true; } m_CurrentGroundInfo = CheckForGround(deltaTime, rotationStream, Vector3.zero); Hop(rotationStream, m_CurrentGroundInfo); if (m_CurrentGroundInfo.isGrounded && !m_IsGrounded) { OnBecomeGrounded.Invoke(); } if (!m_CurrentGroundInfo.isGrounded && m_IsGrounded) { OnBecomeAirborne.Invoke(); } m_IsGrounded = m_CurrentGroundInfo.isGrounded; ApplyAirborneModifier(m_CurrentGroundInfo); GroundInfo nextGroundInfo = CheckForGround(deltaTime, rotationStream, m_Velocity * deltaTime); GroundNormal(deltaTime, ref rotationStream, m_CurrentGroundInfo, nextGroundInfo); TurnKart(deltaTime, ref rotationStream); StartDrift(m_CurrentGroundInfo, nextGroundInfo, rotationStream); StopDrift(deltaTime); CalculateDrivingVelocity(deltaTime, m_CurrentGroundInfo, rotationStream); Vector3 penetrationOffset = SolvePenetration(rotationStream); penetrationOffset = ProcessVelocityCollisions(deltaTime, rotationStream, penetrationOffset); rotationStream = Quaternion.RotateTowards(m_Rigidbody.rotation, rotationStream, rotationCorrectionSpeed * deltaTime); AdjustVelocityByPenetrationOffset(deltaTime, ref penetrationOffset); m_Rigidbody.MoveRotation(rotationStream); m_Rigidbody.MovePosition(m_RigidbodyPosition + m_Movement); //rb.GetPointVelocity(transform.TransformPoint(localWheelPos)); //Debug.Log(LocalSpeed); }
private void Start() { _stats = Registry.ProjectSettings.kartStats; }
Vector3 LocalVelocity(float deltaTime, Quaternion rotationStream, float steeringInput, float accelerationInput, Vector3 velocity, KartStats m_ModifiedStats) { //First turn the kart Vector3 localVelocity = Quaternion.Inverse(rotationStream) * velocity; float forwardReverseSwitch = Mathf.Sign(localVelocity.z); float modifiedSteering = steeringInput * forwardReverseSwitch; float speedProportion = velocity.sqrMagnitude > 0f ? 1f : 0f; float turn = m_ModifiedStats.turnSpeed * modifiedSteering * speedProportion * deltaTime; Quaternion deltaRotation = Quaternion.Euler(0f, turn, 0f); rotationStream *= deltaRotation; //Then calculate velocity localVelocity = Quaternion.Inverse(rotationStream) * velocity; localVelocity.x = Mathf.MoveTowards(localVelocity.x, 0f, m_ModifiedStats.grip * deltaTime); if (accelerationInput == 0) { // No acceleration input. localVelocity.z = Mathf.MoveTowards(localVelocity.z, 0f, m_ModifiedStats.coastingDrag * deltaTime); } else if (accelerationInput > 0) { // Positive acceleration input. localVelocity.z = Mathf.MoveTowards(localVelocity.z, m_ModifiedStats.topSpeed, accelerationInput * m_ModifiedStats.acceleration * deltaTime); } else if (localVelocity.z > 0) { // Negative acceleration input and going forwards. localVelocity.z = Mathf.MoveTowards(localVelocity.z, 0f, -accelerationInput * m_ModifiedStats.braking * deltaTime); } else { // Negative acceleration input and not going forwards. localVelocity.z = Mathf.MoveTowards(localVelocity.z, -m_ModifiedStats.reverseSpeed, -accelerationInput * m_ModifiedStats.reverseAcceleration * deltaTime); } return(rotationStream * localVelocity); }
bool DrivingBackwards(float deltaTime, Quaternion rotationStream, float steeringInput, float accelerationInput, Vector3 velocity, KartStats m_ModifiedStats) { //First turn the kart Vector3 localVelocity = Quaternion.Inverse(rotationStream) * velocity; float forwardReverseSwitch = Mathf.Sign(localVelocity.z); float modifiedSteering = steeringInput * forwardReverseSwitch; float speedProportion = velocity.sqrMagnitude > 0f ? 1f : 0f; float turn = m_ModifiedStats.turnSpeed * modifiedSteering * speedProportion * deltaTime; Quaternion deltaRotation = Quaternion.Euler(0f, turn, 0f); rotationStream *= deltaRotation; //Then calculate velocity localVelocity = Quaternion.Inverse(rotationStream) * velocity; localVelocity.x = Mathf.MoveTowards(localVelocity.x, 0f, m_ModifiedStats.grip * deltaTime); if (accelerationInput < 0 && localVelocity.z <= 0) { return(true); } return(false); }