CoD Modern Warfare style gun script (update 08/07/2015)

Update 8/7/2015 (yeah...it's about time)

Since people are still using this apparently and the thread gets pinged once in a while... it is about time to update the code. Since this was my first post and attempt into Unity scripting way back when... the gun was OK (but pretty crap code). Here are some updated scripts (better code, gun still OK)...

I moved from a single script for all guns approach to a more inherited approach. All of my guns now inherit from my base Gun script. Each child is a different kind of gun but in your code you can still grab it using the base Gun class.

As usual... use these as you see fit and how every you want. If you like them or the end up in something cool.. post back (or pm/mail) and let me see... would be cool to see it actually being used somewhere.

Link to a newer blah webplayer (built today with these scripts)
https://dl.dropboxusercontent.com/u/1475775/CoD/newer/08-07-2015/gun.html

The Code....

[spoiler]

Gun.cs

using UnityEngine;
using System.Collections;


[System.Serializable]
public class Damage
{
    public int amount; // how much damage
    public DamageType type; //what type of damage
}

public enum DamageType
{
    NORMAL,
    FIRE,
    ICE,
    ACID,
    ELECTRIC,
    POISON
}

public enum WeaponType
{
    SEMIAUTO, // burst fire and shotguns fall under this category
    FULLAUTO
}


public class Gun : MonoBehaviour {
    public string weaponName;                         // Name of this weapon
    public WeaponType typeOfWeapon;             // type of weapon, used to determine how the trigger acts
    public bool usePooling = false;             // do we want to use object pooling or instantiation
    public Damage damage = new Damage();        // the damage and type of damage this gun does
    public float projectileSpeed = 100.0f;      // speed that projectile flies at
    public float projectileForce = 10.0f;       // force applied to any rigidbodies the projectile hits
    public float projectileLifeTime = 5.0f;     // how long before the projectile is considered gone and recycleable

    public Transform muzzlePoint = null;        // the muzzle point for this gun, where you want bullets to be spawned

    public int maxPenetration = 1;              // maximum amount of hits detected before the bullet is destroyed
    public float fireRate = 0.5f;               // time betwen shots

    public bool infinteAmmo = false;            // gun can have infinite ammo if thats what you wish
    public int roundsPerClip = 50;              // number of bullets in each clip
    public int ammoReserve = 200;               // number of clips you start with    
    public int roundsLeft;                      // bullets in the gun-- current clip

    public float reloadTime = 2.5f;             // how long it takes to reload in seconds
    protected bool isReloading = false;         // are we currently reloading

    public float baseSpread = 0.2f;             // how accurate the weapon starts out... smaller the number the more accurate
    public float maxSpread = 4.0f;              // maximum inaccuracy for the weapon
    public float spreadPerShot = 0.75f;         // increase the inaccuracy of bullets for every shot
    public float spread = 0.0f;                 // current spread of the gun
    public float decreaseSpreadPerTick = 0.25f;  // amount of accuracy regained per frame when the gun isn't being fired 
    public float spreadDecreaseTicker = 0.5f;   // time in seconds to decrease inaccuracy

    protected float nextFireTime = 0.0f;        // able to fire again on this frame
    protected bool spreadDecreasing = false;    // is the gun currently decrasing the spread

    protected ProjectileInfo bulletInfo = new ProjectileInfo(); // all info about gun that's sent to each projectile


    protected virtual void Start()
    {
        roundsLeft = roundsPerClip; // load gun on startup      
    }

    // all guns handle firing a bit different so give it a blank function that each gun can override
    public virtual void Fire()
    {

    }


    // everything fires a single round the same
    protected virtual void FireOneShot() {

    }

    // reload your weapon
    protected virtual IEnumerator Reload()
    {
        if (isReloading)
        {
            yield break; // if already reloading... exit and wait till reload is finished
        }

        if (ammoReserve > 0)
        {
            isReloading = true; // we are now reloading
            int roundsNeeded = roundsPerClip - roundsLeft; // how many rounds needed to fill the gun
            yield return new WaitForSeconds(reloadTime); // wait for set reload time

            if (ammoReserve < roundsNeeded)
            {
                roundsNeeded = ammoReserve;// if we have less bullets than needed to fill the gun... put all we have in
            }

            roundsLeft += roundsNeeded; // fill up the gun
        }

        isReloading = false; // done reloading
    }


    void DecreaseSpread()
    {
        // decrease the current spread per tick
        spread -= decreaseSpreadPerTick;

        // if the current spread is less then the base spread value, set it to the base
        if (spread <= baseSpread)
        {
            spread = baseSpread;

            // stop the decrease spread function until we need it again
            spreadDecreasing = false;
            CancelInvoke("DecreaseSpread");
        }
    }

    // set all bullet info from the gun's info
    // if you plan to be able to change weapon stats on the fly
    // call this function in the fire function (worst performance but always checkes gun stats before firing)
    // or Always call this just after altering a weapon's stats (best performance since its called once when it's needed)
    // default right now is it is called once in start
    protected void SetupBulletInfo()
    {
        bulletInfo.owner = transform.root.gameObject;   // the Owner of this weapon (GameObject) <- use this for scoreboard and who killed who
        bulletInfo.name = name;                         // Name of this weapon  <- for keeping track of weapon kills / whose killed by what
        bulletInfo.damage.amount = damage.amount;       // amount of damage
        bulletInfo.damage.type = damage.type;           // type of damage
        bulletInfo.force = projectileForce;             // weapon force
        bulletInfo.maxPenetration = maxPenetration;     // max hits
        bulletInfo.maxSpread = maxSpread;               // max weapon spread
        bulletInfo.spread = spread;                     // current weapon spread value
        bulletInfo.speed = projectileSpeed;             // projectile speed
        bulletInfo.owner = transform.root.gameObject;   // this projectile's owner gameobject, useful if you want to know whose killing what for kills/assists or whatever
        bulletInfo.usePool = usePooling;                // do we use object pooling
        bulletInfo.projectileLifeTime = projectileLifeTime; // how long till this bullet just goes away
    }

}

Gun_Physical.cs (since physical and raycast guns behave differently)

using UnityEngine;
using System.Collections;

public class Gun_Physical : Gun {
    public GameObject projectile = null;        // projectile prefab... whatever this gun shoots


    protected override void Start()
    {
        base.Start();
        SetupBulletInfo(); // set a majority of the projectile info
    }

    protected override void FireOneShot () {
        if (roundsLeft > 0)
        {
            Vector3 pos = muzzlePoint.position; // position to spawn bullet is at the muzzle point of the gun      
            Quaternion rot = muzzlePoint.rotation; // spawn bullet with the muzzle's rotation

            bulletInfo.spread = spread; // set this bullet's info to the gun's current spread
            GameObject newBullet;

            if (usePooling)
            {
                newBullet = ObjectPool.pool.GetObjectForType(projectile.name, false);
                newBullet.transform.position = pos;
                newBullet.transform.rotation = rot;
            }
            else
            {
                newBullet = Instantiate(projectile, pos, rot) as GameObject; // create a bullet
                newBullet.name = projectile.name;
            }

            newBullet.GetComponent<Projectile>().SetUp(bulletInfo); // send bullet info to spawned projectile

            spread += spreadPerShot;  // we fired so increase spread

            // if the current spread is greater then the weapons max spread, set it to max
            if (spread >= maxSpread)
            {
                spread = maxSpread;
            }

            // if the spread is not currently decreasing, start it up cause we just fired
            if (!spreadDecreasing)
            {
                InvokeRepeating("DecreaseSpread", spreadDecreaseTicker, spreadDecreaseTicker);
                spreadDecreasing = true;
            }

            // if this gun doesn't have infinite ammo, subtract a round from our clip
            if (!infinteAmmo)
            {
                roundsLeft--;

                // if our clip is empty, start to reload
                if (roundsLeft <= 0)
                {
                    StartCoroutine(Reload());
                }
            }
        }
    }

}

Gun_BurstFire.cs (anything that fires multiple shots per triggerpull)

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// component 'Gun_BurstFire'
/// ADD COMPONENT DESCRIPTION HERE
/// </summary>
[AddComponentMenu("Scripts/Gun_BurstFire")]
public class Gun_BurstFire : Gun_Physical
{
    public int burstCount = 3;
    public float burstLag = 0.1f;


    public override void Fire()
    {
        if (nextFireTime < Time.time)
        {
            StartCoroutine(BurstFire());

            nextFireTime = Time.time + fireRate;
        }
    }

    IEnumerator BurstFire()
    {
        for (int i = 1; i <= burstCount; i++)
        {
            FireOneShot();

            yield return new WaitForSeconds(burstLag);
        }

    }


}

Gun_SingleShot.cs

using UnityEngine;
using System.Collections;


public class Gun_SingleShot : Gun_Physical
{
    public override void Fire()
    {
        if (nextFireTime < Time.time)
        {
            FireOneShot();

            nextFireTime = Time.time + fireRate;
        }
    }  
}

Gun_Shotgun.cs

using UnityEngine;
using System.Collections;

/// <summary>
/// component 'Shotgun'
/// ADD COMPONENT DESCRIPTION HERE
/// </summary>
[AddComponentMenu("Scripts/Shotgun")]
public class Gun_Shotgun : Gun_Physical
{
    public int pelletCount = 8;


    public override void Fire()
    {
        if (nextFireTime < Time.time)
        {

            for (int i = 0; i <= pelletCount; i++)
            {
                FireOneShot();
            }

            nextFireTime = Time.time + fireRate;
        }
    }


}

Projectile.cs (base projectile for all others to inherit from)

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// <summary>
///  Base Class for projectiles, contains common elements to all type of projectiles for other projectile  classes to be derived from.
/// </summary>

public class Projectile : MonoBehaviour {

    protected ProjectileInfo myInfo = new ProjectileInfo();
    protected Vector3 velocity;
    protected int hitCount = 0;
    protected List<Collider> collidersToIgnore = new List<Collider>();
    protected List<Collider> backCollidersToIgnore = new List<Collider>();


    // This is bullet initialization, It gets called by the weapon that fired this projectile
    public virtual void SetUp(ProjectileInfo info)
    {
        myInfo = info;      
        hitCount = 0;
        velocity = myInfo.speed * transform.forward + transform.TransformDirection(Random.Range(-myInfo.maxSpread, myInfo.maxSpread) * myInfo.spread, Random.Range(-myInfo.maxSpread, myInfo.maxSpread) * myInfo.spread, 1);
        collidersToIgnore.Add (myInfo.owner.GetComponent<Collider>());
        backCollidersToIgnore.Add (myInfo.owner.GetComponent<Collider>());
        Invoke("Recycle", myInfo.projectileLifeTime); // set a life time for this projectile
    }

    protected virtual void MakeAHole(RaycastHit hit)
    {      
        foreach (Collider c in collidersToIgnore)
        {
            if (hit.collider == c)
            {
                return;
            }
        }

        BulletHoleManager.bulletHole.SpawnHole(hit);
        collidersToIgnore.Add(hit.collider);
    }

    protected virtual void MakeABackHole(RaycastHit hit)
    {
        foreach (Collider c in backCollidersToIgnore)
        {
            if (hit.collider == c)
            {
                return;
            }
        }

        BulletHoleManager.bulletHole.SpawnHole(hit);
        backCollidersToIgnore.Add(hit.collider);
    }

    protected virtual void Recycle()
    {
        //Clear the colliders this bullet ignores
        collidersToIgnore.Clear ();
        backCollidersToIgnore.Clear ();

        // pool or destroy the bullet when it is no longer used.
        if (myInfo.usePool)
        {
            ObjectPool.pool.PoolObject(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
}



[System.Serializable]
public class ProjectileInfo
{
    public GameObject owner;
    public string name;
    public Damage damage = new Damage();
    public float force;
    public int maxPenetration;
    public float maxSpread;
    public float spread;
    public float speed;
    public bool usePool;
    public float projectileLifeTime;
}

RigidProjectile.cs (projectile based on a rigidbody... cause bullet drop is all the rage)

using UnityEngine;
using System.Collections;

public class RigidProjectile : Projectile
{    
    private Rigidbody myRigid;  

    public override void SetUp(ProjectileInfo info)
    {
        base.SetUp(info);
        myRigid = GetComponent<Rigidbody>();      
        myRigid.velocity = velocity; 
    }

    void FixedUpdate()
    {
       // Debug.DrawLine(transform.position, transform.position + myRigid.velocity / 60, Color.red);
       // Debug.DrawLine(transform.position, transform.position - myRigid.velocity / 30, Color.magenta);

        RaycastHit hit;  // forward hit
        RaycastHit hit2; // rear hit        

        if (Physics.Raycast(transform.position, myRigid.velocity, out hit, (myRigid.velocity.magnitude/Time.deltaTime), ~LayerMask.NameToLayer("Projectiles")))
        {
            // probably shouldn't do this but best way i can think of to avoid
            // multiple hits from same bullet
            //myRigid.MovePosition(hit.point); // move the bullet to the impact point
            transform.position = hit.point;

            if (hit.transform.CompareTag("Ground"))
            {// if we hit dirt... kill the bullet since most weapons don't pierce the earth
                CancelInvoke("Recycle");
                Recycle();
            }

            Health hitObject = hit.transform.GetComponent<Health>();

            if (hitObject)
            {                
                hitObject.Hit(myInfo); // send bullet info to hit object's health component
            }
            else
            {
                MakeAHole(hit); // make a hole anywhere except the players
            }

            hitCount++; // add a hit

            if (hitCount > myInfo.maxPenetration)
            {
                CancelInvoke("Recycle");
                Recycle(); // if hit count exceeds max hits.... kill the bullet
            }
        }

        // this shoots a ray out behind the bullet.
        // use this to add a bullet hole to the back side of a penetrated wall or whatever
        if (Physics.Raycast(transform.position, -myRigid.velocity, out hit2, 2+(myRigid.velocity.magnitude/Time.deltaTime) , ~LayerMask.NameToLayer("Projectiles")))
            {
                if (hit2.transform.CompareTag("Player"))
                {
                    // do nothing since we probably already penetrated the player
                }
                else
                {
                    MakeABackHole(hit2);
                }                
            }
    }  
}

That's it for the main scripts (there are a few others in the download).

[/spoiler]

Link to Direct Downloads of everything:

Unity Package File: https://dl.dropboxusercontent.com/u/1475775/CoD/newer/08-07-2015/Novashot_Guns_08072015.unitypackage

Scripts Only Folder: https://dl.dropboxusercontent.com/u/1475775/CoD/newer/08-07-2015/Novashot_Guns_ScriptsOnly_08072015.zip

Entire Project folder: https://dl.dropboxusercontent.com/u/1475775/CoD/newer/08-07-2015/Novashot_Guns_Project_08072015.zip

....Just noticed... as a bonus apparently since I've already typed this up and linked everything... you get my Health script also.

The original stuff is still below if need be.

Have fun.

The Original Post

[spoiler]

Highlights:
- Multiple Guns in one script
- Tracers
- Bullet Penetration
- bullet randomness, increases over time
- multiple material ready, just needs effects
- Look down sights ready
- Easy

Here's a gun script that I been working on and it does just about everything. I searched for good gun scripts everywhere and got sick of the search; here is a bit of almost every script I seen all added together. It's a machine gun, burst / single shot, shotgun, and a grenade/rocket launcher all-in one script (c# only sorry). With a few changes in variables, you can make almost any weapon you wish.

This gun side script supports variable bullet penetration, bullet creates impact effects and bullet holes on both sides of a penetrated wall, and variable tracers. Gun also has variables for random bullet spread with support for a decrease in accuracy during sustained fire from machine guns.

Burst mode can fire any number of rounds per trigger pull and you can set the time between the rounds fired in the burst. Want a single shot? Set the burst to 1 and done.

Shotgun has a variable for the number of pellets fired per shot.

The Launcher supports both rockets and grenades if you're into noob tubes.

...the scripts have the framework in for multi-player, but hasn't been fully integrated yet, but should be soon. I'm working with the standard unity master server so my multi-player parts will be geared toward that.

Forgot to mention, use the right mouse button(fire2) to look down the sights of your gun.

Here's a Web Player Test of the gun Scripts in action.

CoD Style Weapons WebPlayer

Player with guns Unity Package

If you like what you see, Use and Update these as you see fit. If you happen to add something cool, let everyone else know. Let me know what you think.

Thanks and have fun.

[/spoiler]

333849--11731--$novashot_gun_scripts_136.zip (8.79 KB)
337268--11830--$novashot_cod_style_weapons_117.unitypackage (1.58 MB)
333849--149471--Novashot_Guns_ScriptsOnly_08072015.zip (18 KB)
333849--149472--Novashot_Guns_08072015.unitypackage (20.9 KB)

2 Likes

Great! One slight change is that the rockets do not explode after X seconds. By this, I mean if you shoot up, the rocket appears to go on for infinity. Wouldn't be too hard to add a timer code, though.

Thanks!

Actually, Alex, you could just make the timer code yourself and add it to the rocket prefab. That way when the rocket spawns the script will count how long until it should destroy the rocket and the rocket's children.

AMAZING!

But there is no recoil.

Yeah the current rocket just kills itself after so long...without exploding, but that is a simple fix.

As for the demo, here's the script i used for creating the other weapons and weapon switching.

I had to add a few lines of code in my gun script to use the weapon switch script, so will attach the updated gun.cs also.

Thanks for the feed back.

333860--11732--$gun_732.cs (14.8 KB)
333860--11733--$switchweapons_152.cs (2.4 KB)

I did see a gun script with recoil and walk / run sway in. I might update my gun script to have those features soon.

Wow, pretty impresive. Your first post is a donation of code.

Pretty awesome.

Big time donation! I love them! I was working on some scripts like these, but since you made these you saved me a lot of time!

Thanks so much! :smile:

I updated the gun script a bit to add the ability to choose if you want to run with ray cast bullets or physical bullets. Ray casts are less likely to have "bullet lag" in a multiplayer setting so figured adding the ability was worth while. Also some minor tweaks to the projectile scripts.

I'm going to add in a multiplayer section to my project soon ( just using the unity master server ). I'll post that update when it is working.

Let me know if the scripts help you out... I'd love to hear what type or weapons or how they work in your projects.

337268--11830--$novashot_cod_style_weapons_117.unitypackage (1.58 MB)

Here's the updated scripts with working weapon kick and kick recovery. New version of the web player available also here:

http://dl.dropbox.com/u/1475775/CoD/Novashot_CoD_Style_Weapons.html

Added the updated scripts and prefab packages also.

338712--11854--$novashot_gun_scripts_149.unitypackage (12.8 KB)
338712--11855--$novashot_cod_style_weapons_211.unitypackage (1.79 MB)

Hi there.

Loving your work here, but I've got a few issues getting this to work with my existing set up (Making a third person game myself) and I was wondering if you could post a demo project file or just advise me where you applied which scripts? If you could I'd be grateful!

Thanks.

Looks great, I started over, just cause my own scripts got so messy. I do however get this error, I'm assuming that is because 'offset' is not a function in 'mouselook', did you add another script or modify the mouselook script?

"Assets/New Gun Assets/Weapons/Scripts/Gun.cs(557,46): error CS1061: Type MouseLook' does not contain a definition foroffsetY' and no extension method offsetY' of typeMouseLook' could be found (are you missing a using directive or an assembly reference?)"

NVM, got it solved by adding those vars to MouseLook

Here is a sample project with those gun scripts so you can see how I have it set up on a playable character. It has a basic example of both FPS and Third Person Player modes. It was just thrown together and made sure it was working so it is far from very good, but its enough to show you how to get the weapons in and working.

WebPlayer:
http://dl.dropbox.com/u/1475775/WebPlayer/WebPlayer.html

Project Folder:
http://dl.dropbox.com/u/1475775/WebPlayer/Gun.zip

Actually my real problem is doing damage to my enemies,. hmmmm at the moment they are listening for specific bullets from my old weapon scripts, hmmm fail.

Any ideas to what direction I should be looking at?

I think my old script was overly complicated: Looked like this:

function OnCollisionEnter(whatObject:Collision) {
if (whatObject.transform.name == "bulletHit") {

wakeUpDistance = Vector3.Distance (targetObj.transform.position, transform.position)+1;
var contact : ContactPoint = whatObject.contacts[0];
var rotation = Quaternion.FromToRotation( Vector3.up, contact.normal );

print(whatObject.transform.GetComponent(Projectile).gunType);

switch (whatObject.transform.GetComponent(Projectile).gunType) {

case "Handgun":
blood.particleEmitter.minEmission =10;
blood.particleEmitter.maxEmission = 20;
break;
case "Rifle":
blood.particleEmitter.minEmission =20;
blood.particleEmitter.maxEmission = 25;
break;
case "Machine Gun":
blood.particleEmitter.minEmission =30;
blood.particleEmitter.maxEmission = 50;
break;
case "MP5":
blood.particleEmitter.minEmission = 30;
blood.particleEmitter.maxEmission = 50;
break;
case "Shotgun":
blood.particleEmitter.minEmission =200;
blood.particleEmitter.maxEmission = 300;
break;
}

var zombieBlood : GameObject = Instantiate(blood, contact.point, rotation );

receiveDamage(whatObject.transform.GetComponent(Projectile).damageAmount);
//zombieSpeed=zombieSpeed-0.05;

if (hitPoints<1) {
dieGently();
}
}
}

function receiveDamage(howMuch) {
hitPoints-=howMuch;
return;
}

function dieGently() {
dead=true;
this.rigidbody.isKinematic = true;
Destroy (collider);
AudioSource.PlayClipAtPoint(clip2, Vector3 (101.162, 0.1, 97.67393));
var whichDie ="die"+Mathf.Round(Random.Range(1,3));
animation[whichDie].speed = 5;
animation.CrossFade(whichDie);
Destroy(gameObject, 5);
//~ GameObject.FindWithTag("ZombieText").GetComponent(kills).gameText("zombiesdead");

}

function dieHeadshot() {
dead=true;
// this.rigidbody.isKinematic = true;
Destroy (rigidbody);
Destroy (collider);
AudioSource.PlayClipAtPoint(clip3, Vector3 (101.162, 0.1, 97.67393));
var whichDie ="die"+Mathf.Round(Random.Range(1,3));
animation[whichDie].speed = 5;
animation.CrossFade(whichDie);
Destroy(gameObject, 5);
//~ GameObject.FindWithTag("ZombieText").GetComponent(kills).gameText("zombiesdead");
}

My script treats all bullets about the same no matter of what kind of gun that shot them... except the gun script gives the bullets different properties like damage and velocity. I see your current script uses a different impact emitter depending on the type of gun. It would be an easy enough mod to my code to have the bullets know what type of gun fired it. Each bullet fired by my gun is sent and array of information giving the bullet it's specific propeties:

        bulletInfo[0] = damage;
        bulletInfo[1] = impactForce;
        bulletInfo[2] = maxPenetration;
        bulletInfo[3] = maxSpread;
        bulletInfo[4] = spread;
        bulletInfo[5] = bulletSpeed;

        newBullet.SendMessageUpwards("SetUp", bulletInfo); // send the gun's info to the bullet

You could just as easy add to the array sending the weapon type. You could change the whole array to strings if it would be easier, but then you would need to reconvert the string to a float or int to use it to cause damage. To cause damage my bullet script calls this:

            // send a message to the hit object... let it know it was hit
            bulletInfo[0] = ownersName;        // tell hit object who hit them
            bulletInfo[1] = damage.ToString(); // tell them how much damage they recieved
            // send the message
            hit.collider.SendMessageUpwards("ImHit", bulletInfo, SendMessageOptions.DontRequireReceiver);

This sends a string array to the hit object telling the hit object who hit it and how hard. Each player or AI then has the function "ImHit" attached that will break up the array and use the info:

public void ImHit(string[] info)
    {

        if(!dead)
        {
            string myKiller = info[0];
            float damage = float.Parse(info[1]);

            //Debug.Log(" I been hit by " + myKiller + " for " + damage + " damage");           

            health -= damage; // do some damage

            //Debug.Log("My health is now " + health + " / " + maxHealth);

            if(health<=0)
            {  
                            health = 0;
                dead = true;
                StartCoroutine(Die());
            }
        }
    }

ImHit takse the bullet info and uses it to damage the player. This array is also very easy to add to if you want to send more information to the target about what hit it. In my function it just subtracts health and if health hits 0 it calls my die function.

In your case, i would replace your recieveDamage with something similar to my ImHit and then use it to call your deaths. Your impact effects will be trickier because in my scripts the bullet creates the impact effect, not the hit object. You can modify the code to send the gun types and check what it hits to make the same effects though.

Hope this helps

Awesome, thx for response, will apply and post it here when its working properly.

The third person view needs some work. Allow the player to aim with the mouse, not just the A and D buttons :)

Check the Web player again... I believe you will find some mouse aiming is in for 3rd person now. It's still not pretty, but that construction worker was never meant to carry that weapon anyway :P the project link should be updated as well.

CoD Style Weapons WebPlayer

Player with guns Unity Package

bro....

can u write a single script
only for shotgun.....

i learn fps tutorial, from unity tutorial....
i have made machinegun, and rocket launcher...
and i want to make new weapon like your "shotgun".....

pls help......:p:p
thx before....... :razz::razz:

with the bullet script, how would i make the particle change depending on wot it hits, its cos the case "ground" thing in it already but i tried everthing i know to make it work but it doesnt!!