Beispiel #1
0
    /// <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));
    }
Beispiel #2
0
    //{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");
    }