/// <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)); }
//{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"); }