Creating tank shell script

Hello, I want to make script for tank shell.
For example (AP) armor piercing shell will have parameters like penetration, weight (or mass), potential damage, initial velocity and drag (air resistance based on aerodynamics of the projectile).

I want to fire AP shell with realistic physics. Like I set constant parameters for AP in script (initial velocity, drag, damage) and then I create prefab with this script and then I just create new script winch will Instantiate shell prefab with shell script that will have physics based on that constant parameters and also every shell has different ricochet.
For example AP shell ricochets if α ≥ 70 deg from hitNormal
I want to ask you how to do this this is very hard for me I was thinkink about this alot
also if its hitnormal angle is α < 70 then it should calculate penetration based or armor thickness etc., damage…
I dont know how to do this ricochet thing, I have experienced with ballistic stuff in unity like launching projectiles cannon but I dont know how to do this.
Please help

public class Projectile : MonoBehaviour
{
    Rigidbody rb;

    private float launchAngle;

    private float initialVelocity = 228.6f;

    private float mass = 50.0f;
    private float drag = 0.5f;

    private int AP_PenetrationAngle = 70;

    private int penetration = 20;
    private int damage = 100;

    // Start is called before the first frame update
    private void Start()
    {
        rb = GetComponent<Rigidbody>();

        rb.velocity = this.transform.forward * initialVelocity;
        rb.mass = mass;
        rb.drag = drag;

        launchAngle = this.transform.rotation.x;

        float Vx = initialVelocity * Mathf.Cos(launchAngle); // horizontal velocity
        float Vy = initialVelocity * Mathf.Sin(launchAngle); // vertical velocity

        float TimeAlive = Mathf.Abs(2 * Vy / Physics.gravity.magnitude); // flight time

        Destroy(gameObject, TimeAlive);
    }

    // Update is called once per frame
    private void FixedUpdate()
    {
        obj();
    }

    private void obj()
    {
        // help maybe every line of code is wrong

        // gravity
        rb.velocity += Physics.gravity * Time.fixedDeltaTime;

        // ray
        RaycastHit hit;
        Ray ray = new Ray(this.transform.position, rb.velocity);

        if (Physics.Raycast(ray, out hit)) // I dont know why it doesnt work when sphere hit ground but it detects while is sphere in air
        {
            float ImpactAngle = Mathf.Abs(90.0f - Vector3.Angle(rb.velocity, hit.normal));

            Debug.Log("Impact angle" + "[" + ImpactAngle + "]");

            if (ImpactAngle >= AP_PenetrationAngle)
            {
                // Ricochet

            }
            else if (ImpactAngle < AP_PenetrationAngle)
            {
                // Penetrate

            }
        }
    }
}

A sabot fired from a main battle tank has about 1500 m/s muzzle velocity. 228 m/s is more like starwars blaster velocities :slight_smile:

But even at 228 m/s it’s a bit too fast for rigidbodies, I would use classic raycasting it’s way more accurate at these speeds.

We are doing ballistics with that method and it works well. If you want something visible you can draw a tracer using a line renderer or other custom shader.

1 Like

When you want detailed control over shell behavior, rather than trying to make it with a rigidbody, you run collision queries yourself, using, for example, raycasting.

Tha’ts because for a rigidbody you have no control over shell bouncing. You can decide how bouncy it will be in general, but not ricochet angle. Also, for rigidbody projectiles, you’d want them to be in continuous dynamic collision mode, otherwise they’ll phase through thin object.

Regarding angle. In case of collision or raycast, contact information will return surface normal, and tha’ts what you’ll need to use to decide projectile’s angle.

Okay I understand what you said but can you link me some example of the code for raycast projectile

No, I can’t link an example. Normally you script those projectiles yourself, using Physics.Raycast method

https://docs.unity3d.com/ScriptReference/Physics.Raycast.html

That’s a function that acts like some sort of laser ray and returns what it hits. So in your code you’ll need to shoot it, process what it hits and act accordingly.

To have a ballistic arc, you’d need to manually split projectile flight path into shorter segments, simulating arc’s curvature.

We use the ballistics coefficient in our ballistics sim. It gives us drag and coupled with gravity it gives us a very true to life ballistics arc.

We have tested it with most ammo types, for example M855 (5.56) shot through a M4 (910 m/s) and it matches 1 to 1 with its real ballistics arc.

Terminal ballistics is a much harder task we are working on that currently

I got a PM from TS I respond here so everyone can benefit.

Look here for details about ballistic coefficients,

You know how far the bullet will travel in one frame its just to multiply deltatime with current velocity. This is the raycast length for this frame. Adjust for drag and gravity and your set

1 Like

Can we please keep it in your thread?

I’m reluctant to hand out code, you will not learn anything by it.

There is no bullet. Just raycast, if you want something visual you need to place a prefab each frame at the raycast hit or use a line renderer to simulate a tracer round.

I dont understand, For example I click fire, it should fire shell but I dont use rigidb. so It will be like visual model shell or just trail ? like tracer, im dumb really But I mean the firing part I raycast from my cannon to predicted position (gravity, speed etc.) ? and then what ? What if some tank will come to shell trajectory after I fire
I need steps

Skip the visuals for now, calculate drag and gravity and raycast in this direction max distance should be the distance the bullet can travel in this frame. There is two outcomes of this cast either it hit a collider or it hits nothing, if it hits nothing move the raycast point to the end of last raycast adjustg for drag and gravity and repeat

nxfxre

Anyone know how to fix this ? Raycast seems to be good but my shell step is too big it looks weird, look at trail renderer

Im updating shell object through script, not using rigidbody or collider on shell, just shell hit point and body

We have implemented a fixed update of sorts for our ballistics. We have set a maximum of 5ms for a ballistics frame. If render thread can’t deliver this we split the frame into several raycasts

Edit: this also helps in being closer to the ballistics coefficient.

Im doing this in FixedUpdate too using fixedDeltaTime
I was thinking about same thing like splitting frame into more frames.

offtopic:
Can I contact you on discord or telegram if you have

Yeah fixed update has way to low speed for accurate ballistics. You need to split it at a good interval. We actually don’t use time btw. We use meters we want the projectile to travel max 5 meters in one raycast

Btw this method also works with reducing timescale.

1 Like