void Update() { for (int i = 0; i < bodies.Count - 1; i++) { for (int j = i + 1; j < bodies.Count; j++) { VirtualPhysicsTransform bodyA = bodies[i].PhysicsTransform, bodyB = bodies[j].PhysicsTransform; decimal squardDist = Vector3.DistanceSquared(bodyA.Position, bodyB.Position); decimal forceMagnitude = 0m; if (squardDist > 0.001m) { forceMagnitude = (G * bodyA.Mass * bodyB.Mass) / squardDist; } Vector3 force = (bodyA.Position - bodyB.Position).Normalized * forceMagnitude; //Two birds with one stone bodyA.AddForce(-force); Debug.DrawRay(bodyA.Position, -force / bodyA.Mass, Color.green, Time.deltaTime, false); bodyB.AddForce(force); Debug.DrawRay(bodyB.Position, force / bodyB.Mass, Color.yellow, Time.deltaTime, false); } } }
/// <summary> /// /// </summary> /// <param name="penData"></param> /// <returns>bool willPenetrate, float penetrationDepth</returns> protected virtual Tuple <bool, float> WillPen(TerminalBallisticsData penData) { ProjectileData projData = penData.projectile.projectileData; VirtualPhysicsTransform physicsTransform = penData.projectile.physicsTransform; //(assuming 0 degrees is hitting straight on) //If angleWeHitTarget >= 80 degrees, then richochet if (Vector3.Angle(physicsTransform.Velocity.normalized, -penData.hitInfo.normal) >= 80) { return(new Tuple <bool, float>(false, 0.0f)); //When Unity supports C#7, switch this to the new syntax } //Otherwise, do some more testing float targetDensity = 1000.0f; //{TODO} Hook this up //tex: //$$stoppingDist=\sqrt[3]{\frac{projMass * initVel^2}{targetDensity*projCrossArea * projDragCoefficient}} $$ //Heavily simplified model float stoppingDist = Mathf.Pow( //3rd root (projData.bulletMass * physicsTransform.VelocityMagnitude * physicsTransform.VelocityMagnitude) //{TODO} Make velocity relative to target / (targetDensity * projData.CrossSectionalArea * projData.GetDragCoefficient(physicsTransform.Velocity.magnitude / 343.0f)) //{TODO} Rewrite correctly! , (1.0f / 3.0f) ); return(new Tuple <bool, float>(stoppingDist >= projData.noseLength, stoppingDist)); }
public void Initialise(VirtualPhysicsTransform fromData) { pos = fromData.pos; vel = fromData.vel; prevPos = fromData.prevPos; prevVel = fromData.prevVel; rot = fromData.rot; rotVel = fromData.rotVel; prevRot = fromData.prevRot; prevRotVel = fromData.prevRotVel; mass = fromData.mass; }
//{TODO} Damn this method is long... protected virtual void Penetrate(TerminalBallisticsData penData, float stoppingDist) { ProjectileData projData = penData.projectile.projectileData; VirtualPhysicsTransform physicsTransform = penData.projectile.physicsTransform; float targetDensity = 1000.0f; //{TODO} Hook this up //343.0f - Temporary hardcoded value - 1 mach in air ~= 343 m/s ThicknessData objectThickness = ProjectileHelper.FindThickness( physicsTransform.PrevPosition, physicsTransform.Velocity.normalized, (rCH) => rCH.collider.gameObject == penData.hitInfo.collider.gameObject); //Only colliders on this object Debug.Log($"Thickness: {objectThickness.thickness}m"); //{TODO} Add some check to see if the object thickness was even found //If the projectile stops mid-object, de-activate it if (stoppingDist <= objectThickness.thickness) { penData.projectile.Active = false; Debug.Log($"Stopped after penetrating {stoppingDist}m"); return; } //Otherwise, see how fast we come out the other side physicsTransform.Position = objectThickness.exitPosition; //tex: //$$ v=\sqrt{-\frac{ACpx^3}{m}+u^2}$$ physicsTransform.VelocityMagnitude = Mathf.Sqrt( - ( ( projData.CrossSectionalArea * projData.GetDragCoefficient(physicsTransform.Velocity.magnitude / 343.0f) * targetDensity * objectThickness.thickness * objectThickness.thickness * objectThickness.thickness ) / projData.bulletMass ) + (physicsTransform.VelocityMagnitude * physicsTransform.VelocityMagnitude) ); //Modify the exit direction depending on the projectile velocity //{TODO} Rewrite! float range = 0.25f; physicsTransform.VelocityDirection += Vector3.Lerp( new Vector3( CryptoRand.Range(-range, range), CryptoRand.Range(-range, range), CryptoRand.Range(-range, range)), Vector3.zero, Mathf.Clamp(1 / physicsTransform.VelocityMagnitude, 0, 1) ); Debug.Log($"Stopping distance: {stoppingDist}"); Debug.Log($"Fully penetrated with an exit velocity of {physicsTransform.Velocity.magnitude}m/s"); }