private void ApplyMovementForces(ChassisNode node, float dt) { TrackComponent track = node.track; if ((track.LeftTrack.numContacts + track.RightTrack.numContacts) > 0) { Vector3 vector; Vector3 vector2; float num2; Rigidbody rigidbody = node.rigidbody.Rigidbody; ChassisConfigComponent chassisConfig = node.chassisConfig; this.CalculateNetSurfaceVelocities(node, out vector, out vector2); float num = this.CalculateSlopeCoefficient(rigidbody.transform.up.y); rigidbody.SetVelocitySafe(this.CalculateRigidBodyVelocity(rigidbody, vector, (node.speedConfig.SideAcceleration * num) * dt, out num2)); if ((track.LeftTrack.numContacts > 0) || (track.RightTrack.numContacts > 0)) { Vector3 vector4 = this.CalculateRelativeAngularVelocity(node, dt, num * 1.2f, vector2, num2); Vector3 normalized = rigidbody.transform.InverseTransformDirection(rigidbody.angularVelocity).normalized; if ((Mathf.Abs(node.chassis.TurnAxis) > 0f) && (Mathf.Sign(normalized.y) != Mathf.Sign(node.chassis.TurnAxis))) { float y = Mathf.Lerp(0f, normalized.y, (0.2f * dt) * 60f); vector2 -= rigidbody.transform.TransformDirection(new Vector3(0f, y, 0f)); } rigidbody.SetAngularVelocitySafe(vector2 + vector4); } } }
private float RecalculateRelativeTurnSpeed(ChassisNode node, float dt, float maxTurnSpeed, float relativeTurnSpeed, float slopeCoeff) { ChassisComponent chassis = node.chassis; ChassisConfigComponent chassisConfig = node.chassisConfig; float num = node.speedConfig.TurnAcceleration * 0.01745329f; float num2 = this.CalculateTurnCoefficient(node.track); float num3 = 0f; if (chassis.EffectiveTurnAxis == 0f) { num3 = ((-MathUtil.Sign(relativeTurnSpeed) * num) * slopeCoeff) * dt; if (MathUtil.Sign(relativeTurnSpeed) != MathUtil.Sign(relativeTurnSpeed + num3)) { num3 = -relativeTurnSpeed; } } else { if (this.IsReversedTurn(chassis.EffectiveTurnAxis, relativeTurnSpeed)) { num = node.speedConfig.ReverseTurnAcceleration * 0.01745329f; } num3 = ((chassis.EffectiveTurnAxis * num) * slopeCoeff) * dt; if ((chassis.EffectiveMoveAxis == -1f) && chassisConfig.ReverseBackTurn) { num3 = -num3; } } return(Mathf.Clamp((float)(relativeTurnSpeed + num3), (float)(-maxTurnSpeed * num2), (float)(maxTurnSpeed * num2))); }
public void UpdateTankFalling(FixedUpdateEvent evt, FallingTankNode tank) { TankFallingComponent tankFalling = tank.tankFalling; TrackComponent track = tank.track; RigidbodyComponent rigidbody = tank.rigidbody; TankCollisionComponent tankCollision = tank.tankCollision; ChassisConfigComponent chassisConfig = tank.chassisConfig; Entity tankEntity = tank.Entity; int trackContacts = this.GetTrackContacts(track); int collisionContacts = this.GetCollisionContacts(tankCollision); int num5 = collisionContacts - tankFalling.PreviousCollisionContactsCount; int deltaTrackContacts = trackContacts - tankFalling.PreviousTrackContactsCount; Vector3 previousVelocity = tankFalling.PreviousVelocity; tankFalling.PreviousCollisionContactsCount = collisionContacts; tankFalling.PreviousTrackContactsCount = trackContacts; tankFalling.PreviousVelocity = rigidbody.Rigidbody.velocity; if (deltaTrackContacts > 0) { this.ApplyFall(tankEntity, previousVelocity, tankFalling, track, chassisConfig, tankCollision, rigidbody, true); } else if ((num5 > 0) && (trackContacts == 0)) { this.ApplyFall(tankEntity, previousVelocity, tankFalling, track, chassisConfig, tankCollision, rigidbody, false); } else { this.UpdateGroundedStatus(tankFalling, deltaTrackContacts, collisionContacts, trackContacts); } }
public SuspensionRay(Rigidbody body, Vector3 origin, Vector3 direction, ChassisConfigComponent chassisConfig, ChassisComponent chassis, float damping) { this.rigidbody = body; this.origin = origin; this.direction = direction; this.chassisConfig = chassisConfig; this.chassis = chassis; this.damping = damping; this.ConvertToGlobal(); this.rayHit.distance = chassisConfig.MaxRayLength; this.rayHit.point = this.globalOrigin + (this.globalDirection * chassisConfig.MaxRayLength); }
private float CalculateForcePerRay(ChassisNode node, float dt, float forwardRelativeSpeed) { ChassisConfigComponent chassisConfig = node.chassisConfig; ChassisComponent chassis = node.chassis; float maxSpeed = node.effectiveSpeed.MaxSpeed; TrackComponent track = node.track; Rigidbody rigidbody = node.rigidbody.Rigidbody; float acceleration = node.speed.Acceleration; float num3 = 0f; if (chassis.EffectiveMoveAxis == 0f) { num3 = (-MathUtil.Sign(forwardRelativeSpeed) * acceleration) * dt; if (MathUtil.Sign(forwardRelativeSpeed) != MathUtil.Sign(forwardRelativeSpeed + num3)) { num3 = -forwardRelativeSpeed; } } else { if (this.IsReversedMove(chassis.EffectiveMoveAxis, forwardRelativeSpeed)) { acceleration = node.speedConfig.ReverseAcceleration; } num3 = (chassis.EffectiveMoveAxis * acceleration) * dt; } float f = Mathf.Clamp(forwardRelativeSpeed + num3, -maxSpeed, maxSpeed); float num5 = f - forwardRelativeSpeed; float num6 = 1f; float num7 = (maxSpeed <= 0f) ? num6 : Mathf.Clamp01(1f - Mathf.Abs((float)(forwardRelativeSpeed / maxSpeed))); if ((num7 < num6) && ((chassis.EffectiveMoveAxis * MathUtil.Sign(forwardRelativeSpeed)) > 0f)) { num5 *= num7 / num6; } float num8 = num5 / dt; if ((Mathf.Abs(num8) < 4f) && (Mathf.Abs(f) > (0.5f * maxSpeed))) { num8 = MathUtil.SignEpsilon(num8, 0.1f) * 4f; } int num10 = track.LeftTrack.numContacts + track.RightTrack.numContacts; int num11 = 2 * chassisConfig.NumRaysPerTrack; float num12 = ((num8 * rigidbody.mass) * (num10 + (0.42f * (num11 - track.LeftTrack.numContacts)))) / ((float)num11); return((num10 <= 0) ? num12 : (num12 / ((float)num10))); }
private void CalculateNetSurfaceVelocities(ChassisNode node, out Vector3 surfaceVelocity, out Vector3 angularSurfaceVelocity) { ChassisConfigComponent chassisConfig = node.chassisConfig; TrackComponent track = node.track; Vector3 contactsMidpoint = this.GetContactsMidpoint(chassisConfig, track); surfaceVelocity = Vector3.zero; angularSurfaceVelocity = Vector3.zero; for (int i = 0; i < chassisConfig.NumRaysPerTrack; i++) { this.AddSurfaceVelocitiesFromRay(node, track.LeftTrack.rays[i], contactsMidpoint, ref surfaceVelocity, ref angularSurfaceVelocity); this.AddSurfaceVelocitiesFromRay(node, track.RightTrack.rays[i], contactsMidpoint, ref surfaceVelocity, ref angularSurfaceVelocity); } float num2 = track.LeftTrack.numContacts + track.RightTrack.numContacts; surfaceVelocity = (num2 <= 0f) ? surfaceVelocity : (surfaceVelocity / num2); angularSurfaceVelocity = (num2 <= 0f) ? angularSurfaceVelocity : (angularSurfaceVelocity / num2); }
private Vector3 GetContactsMidpoint(ChassisConfigComponent chassisConfig, TrackComponent tracks) { Vector3 vector = new Vector3(); for (int i = 0; i < chassisConfig.NumRaysPerTrack; i++) { SuspensionRay ray = tracks.LeftTrack.rays[i]; if (ray.hasCollision) { vector += ray.rayHit.point; } ray = tracks.RightTrack.rays[i]; if (ray.hasCollision) { vector += ray.rayHit.point; } } int num2 = tracks.LeftTrack.numContacts + tracks.RightTrack.numContacts; return((num2 != 0) ? (vector / ((float)num2)) : Vector3.zero); }
private Vector3 CalculateRelativeAngularVelocity(ChassisNode node, float dt, float slopeCoeff, Vector3 surfaceAngularVelocity, float forwardRelativeSpeed) { ChassisConfigComponent chassisConfig = node.chassisConfig; TrackComponent track = node.track; Rigidbody rigidbody = node.rigidbody.Rigidbody; float maxTurnSpeed = node.effectiveSpeed.MaxTurnSpeed * 0.01745329f; Vector3 up = rigidbody.transform.up; Vector3 forward = rigidbody.transform.forward; Vector3 lhs = rigidbody.angularVelocity - surfaceAngularVelocity; float relativeTurnSpeed = Vector3.Dot(lhs, up); float forcePerRay = this.CalculateForcePerRay(node, dt, forwardRelativeSpeed); for (int i = 0; i < chassisConfig.NumRaysPerTrack; i++) { this.ApplyForceFromRay(track.LeftTrack.rays[i], rigidbody, forward, forcePerRay); this.ApplyForceFromRay(track.RightTrack.rays[i], rigidbody, forward, forcePerRay); } float num5 = Vector3.Dot(lhs, up); return(lhs + ((this.RecalculateRelativeTurnSpeed(node, dt, maxTurnSpeed, relativeTurnSpeed, slopeCoeff) - num5) * up)); }
private void CreateTracks(ChassisInitNode node, ChassisComponent chassis) { Entity entity = node.Entity; ChassisConfigComponent chassisConfig = node.chassisConfig; Rigidbody rigidbody = node.rigidbody.Rigidbody; BoxCollider boundsCollider = node.tankColliders.BoundsCollider; float trackLength = boundsCollider.size.z * 0.8f; float num2 = boundsCollider.size.x - chassisConfig.TrackSeparation; Vector3 vector3 = boundsCollider.center - new Vector3(0f, boundsCollider.size.y / 2f, 0f); Vector3 trackCenterPosition = vector3 + new Vector3(-0.5f * num2, chassisConfig.NominalRayLength, 0f); Vector3 vector6 = vector3 + new Vector3(0.5f * num2, chassisConfig.NominalRayLength, 0f); float damping = node.damping.Damping; TrackComponent component = new TrackComponent { LeftTrack = new Track(rigidbody, chassisConfig.NumRaysPerTrack, trackCenterPosition, trackLength, chassisConfig, chassis, -1, damping), RightTrack = new Track(rigidbody, chassisConfig.NumRaysPerTrack, vector6, trackLength, chassisConfig, chassis, 1, damping) }; int layerMask = LayerMasks.VISIBLE_FOR_CHASSIS_SEMI_ACTIVE; component.LeftTrack.SetRayсastLayerMask(layerMask); component.RightTrack.SetRayсastLayerMask(layerMask); entity.AddComponent(component); }
private void AdjustSuspensionSpringCoeff(ChassisConfigComponent chassisConfig, ChassisComponent chassis, Rigidbody rigidbody) { float num = Physics.gravity.magnitude * rigidbody.mass; chassis.SpringCoeff = num / ((2 * chassisConfig.NumRaysPerTrack) * (chassisConfig.MaxRayLength - chassisConfig.NominalRayLength)); }
private void CreateSuspensionRays(Rigidbody rigidbody, int numRays, Vector3 trackCenterPosition, float trackLength, ChassisConfigComponent chassisConfig, ChassisComponent chassis, float damping) { this.rays = new SuspensionRay[numRays]; float num = trackLength / ((float)(this.rays.Length - 1)); for (int i = 0; i < numRays; i++) { Vector3 origin = new Vector3(trackCenterPosition.x, trackCenterPosition.y, (trackCenterPosition.z + (0.5f * trackLength)) - (i * num)); this.rays[i] = new SuspensionRay(rigidbody, origin, Vector3.down, chassisConfig, chassis, damping); } }
public Track(Rigidbody rigidbody, int numRays, Vector3 trackCenterPosition, float trackLength, ChassisConfigComponent chassisConfig, ChassisComponent chassis, int side, float damping) { this.side = side; this.CreateSuspensionRays(rigidbody, numRays, trackCenterPosition, trackLength, chassisConfig, chassis, damping); }
private Vector3 GetFallingNrm(bool fallingByTrack, TrackComponent track, ChassisConfigComponent chassisConfig, TankCollisionComponent tankCollision, out bool isFallingOnTank) { Vector3 zero = Vector3.zero; isFallingOnTank = false; if (!fallingByTrack) { Collision collision = tankCollision.Collision; if (!this.CheckTankCollisionNotNull(tankCollision)) { return(zero.normalized); } ContactPoint[] contacts = collision.contacts; if (contacts == null) { return(zero.normalized); } int length = contacts.Length; for (int i = 0; i < length; i++) { ContactPoint point = contacts[i]; zero += point.normal; if (!isFallingOnTank) { Collider otherCollider = point.otherCollider; if (this.ValidateCollider(otherCollider)) { int layer = otherCollider.gameObject.layer; isFallingOnTank |= this.CheckTankLayer(layer); } } } } else { int numRaysPerTrack = chassisConfig.NumRaysPerTrack; SuspensionRay[] rays = track.LeftTrack.rays; SuspensionRay[] rayArray2 = track.RightTrack.rays; for (int i = 0; i < numRaysPerTrack; i++) { SuspensionRay ray = rays[i]; SuspensionRay ray2 = rayArray2[i]; this.ApplyTrackRayNormal(ref zero, ray); this.ApplyTrackRayNormal(ref zero, ray2); if (!isFallingOnTank) { if (ray.hasCollision) { if ((ray.rayHit.collider == null) || (ray.rayHit.collider.gameObject == null)) { return(zero.normalized); } if (this.ValidateCollider(ray.rayHit.collider)) { int layer = ray.rayHit.collider.gameObject.layer; isFallingOnTank |= this.CheckTankLayer(layer); } } if (ray2.hasCollision) { if ((ray2.rayHit.collider == null) || (ray2.rayHit.collider.gameObject == null)) { return(zero.normalized); } if (this.ValidateCollider(ray2.rayHit.collider)) { int layer = ray2.rayHit.collider.gameObject.layer; isFallingOnTank |= this.CheckTankLayer(layer); } } } } } return(zero.normalized); }
private void ApplyFall(Entity tankEntity, Vector3 previousVelocity, TankFallingComponent tankFalling, TrackComponent track, ChassisConfigComponent chassisConfig, TankCollisionComponent tankCollision, RigidbodyComponent rigidbody, bool fallingByTrack) { if ((tankFalling != null) && (!tankFalling.IsGrounded && rigidbody.Rigidbody)) { bool flag; Vector3 planeNormal = this.GetFallingNrm(fallingByTrack, track, chassisConfig, tankCollision, out flag); Vector3 vector2 = Vector3.ProjectOnPlane(previousVelocity, planeNormal); Vector3 position = rigidbody.Rigidbody.transform.position; TankFallingType type = this.DefineFallingCollisionMode(flag, fallingByTrack, planeNormal); TankFallEvent eventInstance = new TankFallEvent { FallingPower = (previousVelocity - vector2).sqrMagnitude, FallingType = type, Velocity = previousVelocity }; if ((type == TankFallingType.SLOPED_STATIC_WITH_COLLISION) && this.CheckTankCollisionNotNull(tankCollision)) { eventInstance.FallingTransform = tankCollision.Collision.transform; } base.ScheduleEvent(eventInstance, tankEntity); tankFalling.IsGrounded = true; } }