protected void FireThrusters(Vector3 vOrientationProp) { //for each axis, applies torque based on the torque available to the axis in the direction indicated by the activation value. //-1 means we are applying torque to effect a negative rotation. +1 does just the opposite. 0 means no torque is needed. Vector3 vThrustProp = vOrientationProp; Vector3 vXTorque = Vector3.zero; Vector3 vYTorque = Vector3.zero; Vector3 vZTorque = Vector3.zero; if (!InputManager.Instance.NoviceMode) { vXTorque = tActivation.x * MTransform.TransformDirection(Vector3.right) * torques.x * Mathf.Abs(vThrustProp.x) * Time.fixedDeltaTime; vYTorque = tActivation.y * MTransform.TransformDirection(Vector3.up) * torques.y * Mathf.Abs(vThrustProp.y) * Time.fixedDeltaTime; vZTorque = tActivation.z * MTransform.TransformDirection(Vector3.forward) * torques.z * Mathf.Abs(vThrustProp.z) * Time.fixedDeltaTime; } else { Vector3 vLocalRight = MTransform.TransformDirection(Vector3.right); vLocalRight.y = 0; vXTorque = tActivation.x * vLocalRight.normalized * torques.x * Mathf.Abs(vThrustProp.x) * Time.fixedDeltaTime; vYTorque = tActivation.y * (Vector3.up) * torques.y * Mathf.Abs(vThrustProp.y) * Time.fixedDeltaTime; } if (!MLandingAbility.Landed) { Vector3 localVelocity = MTransform.InverseTransformDirection(m_rigidbody.velocity); float ForwardSpeed = Mathf.Max(0, localVelocity.z); Vector3 vTorque = Vector3.zero; if (InputManager.Instance.NoviceMode) { Quaternion localRotation = MTransform.localRotation; Quaternion axisRotation = Quaternion.AngleAxis(localRotation.eulerAngles[0], rotateAround); float angleFromMin = Quaternion.Angle(axisRotation, minQuaternion); float angleFromMax = Quaternion.Angle(axisRotation, maxQuaternion); float fDotUp = Vector3.Dot(MTransform.forward, Vector3.up); float fDotDown = Vector3.Dot(MTransform.forward, -Vector3.up); bool bDiffUp = (1f - fDotUp) < 0.1f; bool bDiffDown = (1f - fDotDown) < 0.1f; bool bDiff = bDiffUp || bDiffDown; bool bDownDirMovement = bDiffUp && !bDiffDown && tActivation.x > 0; bool bUpDirMovement = bDiffDown && !bDiffUp && tActivation.x < 0; if (!bDiff || bDownDirMovement || bUpDirMovement) { if (tActivation.x != 0) { vTorque += vXTorque; } } else { Vector3 vAngular = m_rigidbody.angularVelocity; vAngular.x = 0f; vAngular.z = 0f; m_rigidbody.angularVelocity = vAngular; } if (tActivation.y != 0) { vTorque += vYTorque; } } else { if (tActivation.x != 0) { vTorque += vXTorque; } if (tActivation.y != 0) { vTorque += vYTorque; } if (tActivation.z != 0) { vTorque += vZTorque; } } if (AllowTorquing && !InputManager.Instance.NoviceMode) { m_rigidbody.AddTorque(vTorque); } else if (AllowTorquing && InputManager.Instance.NoviceMode) { m_rigidbody.AddTorque(vTorque); } } if (InputManager.Instance.IsMovement() && !m_playerShip.m_airBrakePress.IsActive) { SpeedStat.Accelerate(); if (MTransform.forward.y < 0f) { Vector3 vDownForce = Physics.gravity.y * GameSimulation.Instance.GravityMultiplier * MTransform.forward.y * MTransform.forward * GameSimulation.Instance.GravityMultiplier; m_rigidbody.AddForce(vDownForce, ForceMode.Force); } } else { SpeedStat.Decelerate(); } if (!MLandingAbility.Landed) { SpeedStat.AddForce(vThrustProp.x, vThrustProp.y); } bool bDashCheck = m_playerShip.MDashAbility == null || (m_playerShip.MDashAbility != null && m_playerShip.MDashAbility.Cooldown.IsMin()) || (m_playerShip.MSpeedGateEffect.ForcesActive()); if (m_bAeroSteering) { if ((Rigidbody.velocity.magnitude > 0 && bDashCheck) || DisableAeroDynamic) { AeroDynamicEffect.ModifyCurrent(Time.fixedDeltaTime * m_fAeroGainMod); // compare the direction we're pointing with the direction we're moving: m_AeroFactor = Vector3.Dot(MTransform.forward, Rigidbody.velocity.normalized); // multipled by itself results in a desirable rolloff curve of the effect m_AeroFactor *= m_AeroFactor; // Finally we calculate a new velocity by bending the current velocity direction towards // the the direction the plane is facing, by an amount based on this aeroFactor Vector3 newVelocity = Vector3.Lerp(Rigidbody.velocity, MTransform.forward * Rigidbody.velocity.magnitude, m_AeroFactor * Rigidbody.velocity.magnitude * AeroDynamicEffect.Current * Time.fixedDeltaTime); Rigidbody.velocity = newVelocity; } else { AeroDynamicEffect.SetToMin(); } } }
protected void RCS(Vector3 vTurnProp) { //angular acceleration = torque/mass rates = torques / m_rigidbody.mass; Vector3 vThrustProp = vTurnProp; // //determine targer rates of rotation based on user input as a percentage of the maximum angular velocity m_vTargetVelocity = new Vector3(vThrustProp.x * rates.x, vThrustProp.y * rates.y, vThrustProp.z * rates.z); // //take the rigidbody.angularVelocity and convert it to local space; we need this for comparison to target rotation velocities curVelocity = MTransform.InverseTransformDirection(m_rigidbody.angularVelocity); //**************************************************************************************************************** //For each axis: If the ship's current rate of rotation does not equal the desired rate of rotation, first check to see //if it is a matter of drift or "jittering", which is when it keeps jumping from positive to negative to positive thrust because the //values are so close to zero (to see what I mean, set snapThreshold = 0, rotate the ship on multiple axes, then let it try //to come to a complete stop. It won't.) If it is just drift/jittering, turn off the thrust for the axis, and just set the current //angular velocity to the target angular velocity. Otherwise, the user is still giving input, and we haven't reached the //desired rate of rotation. In that case, we set the axis activation value = to the direction in which we need thrust. //**************************************************************************************************************** if (curVelocity.x != m_vTargetVelocity.x) { if (Mathf.Abs(m_vTargetVelocity.x - curVelocity.x) < rates.x * Time.fixedDeltaTime * snapThreshold) { tActivation.x = 0; curVelocity.x = m_vTargetVelocity.x; } else { tActivation.x = Mathf.Sign(m_vTargetVelocity.x - curVelocity.x); } } if (curVelocity.y != m_vTargetVelocity.y) { if (Mathf.Abs(m_vTargetVelocity.y - curVelocity.y) < rates.y * Time.fixedDeltaTime * snapThreshold) { tActivation.y = 0; curVelocity.y = m_vTargetVelocity.y; } else { tActivation.y = Mathf.Sign(m_vTargetVelocity.y - curVelocity.y); } } if (curVelocity.z != m_vTargetVelocity.z) { if (Mathf.Abs(m_vTargetVelocity.z - curVelocity.z) < rates.z * Time.fixedDeltaTime * snapThreshold) { tActivation.z = 0; curVelocity.z = m_vTargetVelocity.z; } else { tActivation.z = Mathf.Sign(m_vTargetVelocity.z - curVelocity.z); } } //here, we manually set the rigidbody.angular velocity to the value of our current velocity. //this is done to effect the manual changes we may have made on any number of axes. //if we didn't do this, the jittering would continue to occur. if (InputManager.Instance.NoviceMode) { } else { m_rigidbody.angularVelocity = MTransform.TransformDirection(curVelocity); } //call the function that actually handles applying the torque FireThrusters(vTurnProp); }