Unity Community


Page 1 of 4 123 ... LastLast
Results 1 to 20 of 66

  1. Location
    Michigan
    Posts
    201

    CoD Modern Warfare style gun script

    New as of August 13, 2013 **********

    Well I've been talking about updating the code for this for quite some time and I guess I've just been to lazy to actually get around to it.... well not today. The older code was pretty much the first weapon scripts I ever made when I started using Unity so they worked but had a few issues. Hopefully I worked some of the issues out with this.

    First of all I started with a few Base Classes which my other scripts will use or inherit from:

    Classes.cs - just a few generic classes other scripts use
    Code:  
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [System.Serializable]
    5. public class ProjectileInfo
    6. {
    7.     public GameObject owner;
    8.     public Damage damage = new Damage();
    9.     public float force;
    10.     public int maxPenetration;
    11.     public float maxSpread;
    12.     public float spread;
    13.     public float speed;
    14.     public bool usePool;
    15.     public float projectileLifeTime;
    16. }
    17.  
    18. [System.Serializable]
    19. public class Damage
    20. {
    21.     public int amount; // how much damage
    22.     public DamageType type; //what type of damage
    23. }
    24.  
    25. [System.Serializable]
    26. public class Resistance
    27. {
    28.     public float normal;
    29.     public float fire;
    30.     public float ice;
    31.     public float acid;
    32.     public float electric;
    33.     public float poison;
    34. }


    Enums.cs - Enums the scripts will use
    Code:  
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public enum DamageType
    5. {
    6.     NORMAL,
    7.     FIRE,
    8.     ICE,
    9.     ACID,
    10.     ELECTRIC,
    11.     POISON
    12. }
    13.  
    14. public enum MaterialTypes
    15. {
    16.     UNKNOWN,
    17.     WOOD,
    18.     STONE,
    19.     METAL
    20. }
    21.  
    22. public enum WeaponType
    23. {
    24.     SEMIAUTO, // burst fire and shotguns fall under this category
    25.     FULLAUTO
    26. }


    Gun.cs - This is the basic gun script, all gun types will inherit from this base class
    Code:  
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Gun : MonoBehaviour {
    5.  
    6.     public WeaponType typeOfWeapon;             // type of weapon, used to determine how the trigger acts
    7.     public bool usePooling = false;             // do we want to use object pooling or instantiation
    8.     public GameObject projectile = null;        // projectile prefab... whatever this gun shoots
    9.     public Damage damage = new Damage();        // the damage and type of damage this gun does
    10.     public float projectileSpeed = 100.0f;      // speed that projectile flies at
    11.     public float projectileForce = 10.0f;       // force applied to any rigidbodies the projectile hits
    12.     public float projectileLifeTime = 5.0f;     // how long before the projectile is considered gone and recycleable
    13.  
    14.     public Transform muzzlePoint = null;        // the muzzle point for this gun, where you want bullets to be spawned
    15.  
    16.     public int maxPenetration = 1;              // maximum amount of hits detected before the bullet is destroyed
    17.     public float fireRate = 0.5f;               // time betwen shots
    18.  
    19.     public bool infinteAmmo = false;            // gun can have infinite ammo if thats what you wish
    20.     public int roundsPerClip = 50;              // number of bullets in each clip
    21.     public int numberOfClips = 5;               // number of clips you start with
    22.     public int maxNumberOfClips = 10;           // maximum number of clips you can hold
    23.     public int roundsLeft;                      // bullets in the gun-- current clip
    24.  
    25.     public float reloadTime = 2.5f;             // how long it takes to reload in seconds
    26.     protected bool isReloading = false;         // are we currently reloading
    27.  
    28.     public float baseSpread = 0.2f;             // how accurate the weapon starts out... smaller the number the more accurate
    29.     public float maxSpread = 4.0f;              // maximum inaccuracy for the weapon
    30.     public float spreadPerShot = 0.05f;         // increase the inaccuracy of bullets for every shot
    31.     public float spread = 0.0f;                 // current spread of the gun
    32.     public float decreaseSpreadPerTick = 0.5f;  // amount of accuracy regained per frame when the gun isn't being fired
    33.     public float spreadDecreaseTicker = 1.0f;   // time in seconds to decrease inaccuracy
    34.  
    35.     protected float nextFireTime = 0.0f;        // able to fire again on this frame
    36.     protected bool spreadDecreasing = false;    // is the gun currently decrasing the spread
    37.  
    38.     protected ProjectileInfo bulletInfo = new ProjectileInfo(); // all info about gun thats sent to each projectile
    39.  
    40.  
    41.     void Start()
    42.     {
    43.         roundsLeft = roundsPerClip; // load gun on startup
    44.         SetupBulletInfo(); // set a majority of the projectile info
    45.     }
    46.  
    47.     // all guns handle firing a bit different so give it a blank function that each gun can override
    48.     public virtual void Fire()
    49.     {
    50.  
    51.     }
    52.  
    53.    
    54.     // everything fires a single round the same
    55.     protected virtual void FireOneShot() {
    56.         if (roundsLeft > 0)
    57.         {
    58.             Vector3 pos = muzzlePoint.position; // position to spawn bullet is at the muzzle point of the gun      
    59.             Quaternion rot = muzzlePoint.rotation; // spawn bullet with the muzzle's rotation
    60.  
    61.             bulletInfo.spread = spread; // set this bullet's info to the gun's current spread
    62.             GameObject newBullet;
    63.  
    64.             if (usePooling)
    65.             {
    66.                 newBullet = ObjectPool.pool.GetObjectForType(projectile.name, true);
    67.                 newBullet.transform.position = pos;
    68.                 newBullet.transform.rotation = rot;
    69.             }
    70.             else
    71.             {
    72.                 newBullet = Instantiate(projectile, pos, rot) as GameObject; // create a bullet
    73.             }
    74.            
    75.             newBullet.GetComponent<Projectile>().SetUp(bulletInfo); // send bullet info to spawned projectile
    76.  
    77.             spread += spreadPerShot;  // we fired so increase spread
    78.  
    79.             // if the current spread is greater then the weapons max spread, set it to max
    80.             if (spread >= maxSpread)
    81.             {
    82.                 spread = maxSpread;
    83.             }
    84.  
    85.             // if the spread is not currently decreasing, start it up cause we just fired
    86.             if (!spreadDecreasing)
    87.             {
    88.                 InvokeRepeating("DecreaseSpread", spreadDecreaseTicker, spreadDecreaseTicker);
    89.                 spreadDecreasing = true;
    90.             }            
    91.  
    92.             // if this gun doesn't have infinite ammo, subtract a round from our clip
    93.             if (!infinteAmmo)
    94.             {
    95.                 roundsLeft--;
    96.  
    97.                 // if our clip is empty, start to reload
    98.                 if (roundsLeft <= 0)
    99.                 {
    100.                    StartCoroutine(Reload());
    101.                 }
    102.             }
    103.         }
    104.     }
    105.  
    106.     // reload your weapon
    107.     protected virtual IEnumerator Reload()
    108.     {
    109.         if (isReloading)
    110.         {
    111.             yield break; // if already reloading... exit and wait till reload is finished
    112.         }
    113.  
    114.         if (numberOfClips > 0)
    115.         {
    116.             isReloading = true; // we are now reloading
    117.             numberOfClips--; // take away a clip
    118.             yield return new WaitForSeconds(reloadTime); // wait for set reload time
    119.             roundsLeft = roundsPerClip; // fill up the gun
    120.         }
    121.  
    122.         isReloading = false; // done reloading
    123.     }
    124.  
    125.  
    126.     void DecreaseSpread()
    127.     {
    128.         // decrease the current spread per tick
    129.         spread -= decreaseSpreadPerTick;
    130.  
    131.  
    132.         // if the current spread is less then the base spread value, set it to the base
    133.         if (spread <= baseSpread)
    134.         {
    135.             spread = baseSpread;
    136.  
    137.             // stop the decrease spread function until we need it again
    138.             spreadDecreasing = false;
    139.             CancelInvoke("DecreaseSpread");
    140.         }
    141.     }
    142.  
    143.  
    144.     // set all bullet info from the gun's info
    145.     protected void SetupBulletInfo()
    146.     {
    147.         bulletInfo.damage.amount = damage.amount;       // amount of damage
    148.         bulletInfo.damage.type = damage.type;           // type of damage
    149.         bulletInfo.force = projectileForce;             // weapon force
    150.         bulletInfo.maxPenetration = maxPenetration;     // max hits
    151.         bulletInfo.maxSpread = maxSpread;               // max weapon spread
    152.         bulletInfo.spread = spread;                     // current weapon spread value
    153.         bulletInfo.speed = projectileSpeed;             // projectile speed
    154.         bulletInfo.owner = transform.root.gameObject;   // this projectile's owner gameobject, useful if you want to know whose killing what for kills/assists or whatever
    155.         bulletInfo.usePool = usePooling;                // do we use object pooling
    156.         bulletInfo.projectileLifeTime = projectileLifeTime;
    157.     }
    158. }


    ObjectPool.cs - a basic object pool script... I forget where I found this but it was somewhere on the forums
    Code:  
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5.  
    6. public class ObjectPool : MonoBehaviour
    7. {
    8.     public static ObjectPool pool;
    9.  
    10.     /// <summary>
    11.     /// The object prefabs which the pool can handle.
    12.     /// </summary>
    13.     public GameObject[] objectPrefabs;
    14.  
    15.     /// <summary>
    16.     /// The pooled objects currently available.
    17.     /// </summary>
    18.     public List<GameObject>[] pooledObjects;
    19.  
    20.     /// <summary>
    21.     /// The amount of objects of each type to buffer.
    22.     /// </summary>
    23.     public int[] amountToBuffer;
    24.  
    25.     public int defaultBufferAmount = 3;
    26.  
    27.     /// <summary>
    28.     /// The container object that we will keep unused pooled objects so we dont clog up the editor with objects.
    29.     /// </summary>
    30.     protected GameObject containerObject;
    31.  
    32.     void Awake()
    33.     {
    34.         pool = this;
    35.     }
    36.  
    37.     // Use this for initialization
    38.     void Start()
    39.     {
    40.         containerObject = new GameObject("ObjectPool");
    41.  
    42.         //Loop through the object prefabs and make a new list for each one.
    43.         //We do this because the pool can only support prefabs set to it in the editor,
    44.         //so we can assume the lists of pooled objects are in the same order as object prefabs in the array
    45.         pooledObjects = new List<GameObject>[objectPrefabs.Length];
    46.  
    47.         int i = 0;
    48.         foreach (GameObject objectPrefab in objectPrefabs)
    49.         {
    50.             pooledObjects[i] = new List<GameObject>();
    51.  
    52.             int bufferAmount;
    53.  
    54.             if (i < amountToBuffer.Length) bufferAmount = amountToBuffer[i];
    55.             else
    56.                 bufferAmount = defaultBufferAmount;
    57.  
    58.             for (int n = 0; n < bufferAmount; n++)
    59.             {
    60.                 GameObject newObj = Instantiate(objectPrefab) as GameObject;
    61.                 newObj.name = objectPrefab.name;
    62.                 PoolObject(newObj);
    63.             }
    64.  
    65.             i++;
    66.         }
    67.     }
    68.  
    69.     /// <summary>
    70.     /// Gets a new object for the name type provided.  If no object type exists or if onlypooled is true and there is no objects of that type in the pool
    71.     /// then null will be returned.
    72.     /// </summary>
    73.     /// <returns>
    74.     /// The object for type.
    75.     /// </returns>
    76.     /// <param name='objectType'>
    77.     /// Object type.
    78.     /// </param>
    79.     /// <param name='onlyPooled'>
    80.     /// If true, it will only return an object if there is one currently pooled.
    81.     /// </param>
    82.     public GameObject GetObjectForType(string objectType, bool onlyPooled)
    83.     {
    84.         for (int i = 0; i < objectPrefabs.Length; i++)
    85.         {
    86.             GameObject prefab = objectPrefabs[i];
    87.  
    88.            // Debug.Log(" if ( "+prefab.name+" == "+ objectType+" )");
    89.             if (prefab.name == objectType)
    90.             {
    91.  
    92.                 if (pooledObjects[i].Count > 0)
    93.                 {
    94.                     GameObject pooledObject = pooledObjects[i][0];
    95.                     pooledObjects[i].RemoveAt(0);
    96.                     pooledObject.transform.parent = null;
    97.                     pooledObject.SetActiveRecursively(true);
    98.  
    99.                     //a few objects need to have some values reset... send them a message to do so, others will ignore it
    100.                     pooledObject.SendMessageUpwards("ResetMe", SendMessageOptions.DontRequireReceiver);
    101.  
    102.                     return pooledObject;
    103.  
    104.                 }
    105.                 else if (!onlyPooled)
    106.                 {
    107.                     return Instantiate(objectPrefabs[i]) as GameObject;
    108.                 }
    109.  
    110.                 break;
    111.  
    112.             }
    113.         }
    114.  
    115.         //If we have gotten here either there was no object of the specified type or non were left in the pool with onlyPooled set to true
    116.         return null;
    117.     }
    118.  
    119.     /// <summary>
    120.     /// Pools the object specified.  Will not be pooled if there is no prefab of that type.
    121.     /// </summary>
    122.     /// <param name='obj'>
    123.     /// Object to be pooled.
    124.     /// </param>
    125.     public void PoolObject(GameObject obj)
    126.     {
    127.         for (int i = 0; i < objectPrefabs.Length; i++)
    128.         {
    129.             if (objectPrefabs[i].name == obj.name)
    130.             {
    131.                 obj.transform.position = new Vector3(5000.0f, 5000.0f, 5000.0f); // move the pooled object out of the game space
    132.                 obj.SetActiveRecursively(false);
    133.                 obj.transform.parent = containerObject.transform;
    134.                 pooledObjects[i].Add(obj);
    135.                 return;
    136.             }
    137.         }
    138.     }
    139.    
    140.  
    141. }


    Since most of the gun code is in the base class, actual weapon scripts are quite small and easy to manage.
    Here are the basic gun scripts:

    Gun_Burstfire.cs - Basic burst fire weapon, choose how many shots per burst and delay in burst
    Code:  
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. /// <summary>
    6. /// component 'Gun_BurstFire'
    7. /// ADD COMPONENT DESCRIPTION HERE
    8. /// </summary>
    9. [AddComponentMenu("Scripts/Gun_BurstFire")]
    10. public class Gun_BurstFire : Gun
    11. {
    12.     public int burstCount = 3;
    13.     public float burstLag = 0.1f;
    14.  
    15.  
    16.     public override void Fire()
    17.     {
    18.         if (nextFireTime < Time.time)
    19.         {
    20.             StartCoroutine(BurstFire());
    21.            
    22.             nextFireTime = Time.time + fireRate;
    23.         }
    24.     }
    25.  
    26.     IEnumerator BurstFire()
    27.     {
    28.         for (int i = 1; i <= burstCount; i++)
    29.         {
    30.             FireOneShot();
    31.  
    32.             yield return new WaitForSeconds(burstLag);
    33.         }
    34.     }
    35. }

    Gun_Shotgun.cs - a shotgun script
    Code:  
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. /// <summary>
    5. /// component 'Shotgun'
    6. /// ADD COMPONENT DESCRIPTION HERE
    7. /// </summary>
    8. [AddComponentMenu("Scripts/Shotgun")]
    9. public class Gun_Shotgun : Gun
    10. {
    11.     public int pelletCount = 8;
    12.    
    13.     public override void Fire()
    14.     {
    15.         if (nextFireTime < Time.time)
    16.         {
    17.  
    18.             for (int i = 0; i <= pelletCount; i++)
    19.             {
    20.                 FireOneShot();
    21.             }
    22.  
    23.             nextFireTime = Time.time + fireRate;
    24.         }
    25.     }
    26. }

    Gun_SingleShot.cs - Basic weapon that fires 1 time per trigger pull
    Code:  
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4.  
    5. public class Gun_SingleShot : Gun
    6. {
    7.  
    8.     public override void Fire()
    9.     {
    10.         if (nextFireTime < Time.time)
    11.         {
    12.             FireOneShot();
    13.  
    14.             nextFireTime = Time.time + fireRate;
    15.         }
    16.     }  
    17. }


    My projectile script is still being worked on since I don't feel it is optimized enough but since my weapon script requires it I'll post what I have so far here... just remember it needs some love and isn't a final version .

    Projectile.cs - projectile script, requires a rigidbody... I also go into the physics section and make the projectile layer so it doesn't collide with any other layer... projectile uses raycast to do its work so we want it to avoid collisions.
    Code:  
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Projectile : MonoBehaviour
    5. {
    6.     private ProjectileInfo myInfo = new ProjectileInfo();
    7.     private Rigidbody myRigid;
    8.     private Vector3 velocity;
    9.     private int hitCount = 0;
    10.  
    11.     public void SetUp(ProjectileInfo info)
    12.     {
    13.         myInfo = info;
    14.         myRigid = rigidbody;
    15.         hitCount = 0;
    16.         velocity = myInfo.speed * transform.forward + transform.TransformDirection(Random.Range(-myInfo.maxSpread, myInfo.maxSpread) * myInfo.spread, Random.Range(-myInfo.maxSpread, myInfo.maxSpread) * myInfo.spread, 1);
    17.        
    18.  
    19.         myRigid.velocity = velocity;
    20.        
    21.         Invoke("Recycle", myInfo.projectileLifeTime);
    22.     }
    23.  
    24.     void FixedUpdate()
    25.     {
    26.         Debug.DrawLine(transform.position, transform.position + myRigid.velocity / 60, Color.red);
    27.         Debug.DrawLine(transform.position, transform.position - myRigid.velocity / 30, Color.magenta);
    28.  
    29.         RaycastHit hit;  // forward hit
    30.         RaycastHit hit2; // rear hit
    31.        
    32.        
    33.         if (Physics.Raycast(transform.position, myRigid.velocity, out hit, 10.0f, ~LayerMask.NameToLayer("Projectiles")))
    34.         {
    35.             // probably shouldn't do this but best way i can think of to avoid
    36.             // multiple hits from same bullet
    37.             myRigid.MovePosition(hit.point); // move the bullet to the impact point
    38.  
    39.            
    40.             if (hit.transform.CompareTag("Ground"))
    41.             {// if we hit dirt... kill the bullet since most weapons don't pierce the earth
    42.                 CancelInvoke("Recycle");
    43.                 Recycle();
    44.             }
    45.            
    46.             if(hit.transform.CompareTag("Player"))
    47.             {
    48.                 // try to grab a health component from a player Object
    49.                 Health hitObject = hit.transform.GetComponent<Health>();          
    50.  
    51.                 // if the hit object has a Health component... let it know it was hit
    52.                 if (hitObject)
    53.                 {                
    54.                     hitObject.Hit(myInfo); // send bullet info to hit object's health component
    55.                 }
    56.             }
    57.             else
    58.             {
    59.                 MakeAHole(hit);
    60.             }
    61.  
    62.             hitCount++; // add a hit
    63.  
    64.             if (hitCount > myInfo.maxPenetration)
    65.             {
    66.                 CancelInvoke("Recycle");
    67.                 Recycle(); // if hit count exceeds max hits.... kill the bullet
    68.             }
    69.         }
    70.  
    71.         // this shoots a ray out behind the bullet.
    72.         // use this to add a bullet hole to the back side of a penetrated wall or whatever
    73.         if (Physics.Raycast(transform.position, -myRigid.velocity, out hit2, 2.0f , ~LayerMask.NameToLayer("Projectiles")))
    74.             {
    75.                 if (hit2.transform.CompareTag("Player"))
    76.                 {
    77.                     // do nothing since we probably already penetrated the player
    78.                 }
    79.                 else
    80.                 {
    81.                     MakeAHole(hit2);
    82.                 }
    83.                
    84.             }
    85.        
    86.     }
    87.  
    88.      void MakeAHole(RaycastHit hit)
    89.      {
    90.          BulletHoleManager.bulletHole.SpawnHole(hit);
    91.      }
    92.    
    93.     void Recycle()
    94.     {
    95.         if (myInfo.usePool)
    96.         {
    97.             ObjectPool.pool.PoolObject(gameObject);
    98.         }
    99.         else
    100.         {
    101.             Destroy(gameObject);
    102.         }
    103.     }
    104. }

    The bullet hole code is also in progress, but the projectile requires it so here it is

    BulletHoleManager.cs - this is meant to manage all bullet holes but is about half completed at the moment
    Code:  
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. /// <summary>
    6. ///
    7. /// Just a script to attach bullet hole prefabs to so the weapon/projectile scripts can
    8. /// access them easily and can be changed out without changing weapon/projectile code
    9. ///
    10. /// </summary>
    11.  
    12. public class BulletHoleManager : MonoBehaviour
    13. {
    14.     public static BulletHoleManager bulletHole;
    15.    
    16.     public List<GameObject> holes = new List<GameObject>(); // generic holes
    17.     public List<GameObject> woodHoles = new List<GameObject>();
    18.     public List<GameObject> metalHoles = new List<GameObject>();
    19.     public List<GameObject> stoneHoles = new List<GameObject>();
    20.  
    21.     public List<GameObject> activeHoles = new List<GameObject>(); // currently active bullet holes
    22.  
    23.     void Start()
    24.     {
    25.         bulletHole = this;
    26.     }
    27.  
    28.     public void SpawnHole(RaycastHit hit)
    29.     {
    30.         Vector3 pos = hit.point + hit.normal * 0.01f;
    31.         int i = 0;
    32.         GameObject newHole;
    33.         MaterialTypes mat = MaterialTypes.UNKNOWN;
    34.  
    35.         switch (hit.transform.tag)
    36.         {
    37.             case "Wood":
    38.                 mat = MaterialTypes.WOOD;
    39.                 break;
    40.             default:
    41.                 mat = MaterialTypes.UNKNOWN;
    42.                 break;
    43.         }
    44.  
    45.        
    46.         switch (mat)
    47.         {
    48.             case MaterialTypes.METAL:
    49.                 i = Random.Range(0, metalHoles.Count);
    50.                 newHole = ObjectPool.pool.GetObjectForType(metalHoles[i].name, false);
    51.                 newHole.transform.position = pos;
    52.                 newHole.transform.rotation = rot;
    53.                 break;
    54.             case MaterialTypes.STONE:
    55.                 i = Random.Range(0, stoneHoles.Count);
    56.                 newHole = ObjectPool.pool.GetObjectForType(stoneHoles[i].name, false);
    57.                 newHole.transform.position = pos;
    58.                 newHole.transform.rotation = rot;
    59.                 break;
    60.             case MaterialTypes.WOOD:
    61.                 i = Random.Range(0, woodHoles.Count);
    62.                 newHole = ObjectPool.pool.GetObjectForType(woodHoles[i].name, false);
    63.                 newHole.transform.position = pos;
    64.                 newHole.transform.rotation = rot;
    65.                 break;
    66.             default:
    67.                 i = Random.Range(0, holes.Count);
    68.                 newHole = ObjectPool.pool.GetObjectForType(holes[i].name, false);
    69.                 newHole.transform.position = pos;
    70.                 newHole.transform.rotation = rot;
    71.                 break;
    72.         }
    73.  
    74.         newHole.transform.parent = transform;
    75.         activeHoles.Add(newHole);
    76.     }
    77. }

    BulletHole.cs - basically a timer for a bullet hole to recycle itself until the manager script is complete
    Code:  
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4.  
    5. public class BulletHole : MonoBehaviour
    6. {
    7.     public float lifeTime = 15.0f;
    8.  
    9.     void Start()
    10.     {
    11.         Invoke("Recycle", lifeTime);
    12.     }
    13.  
    14.     public void ForceRecycle()
    15.     {
    16.         // cancel the invoke and recycle now no matter how much life time was left
    17.         CancelInvoke("Recycle");
    18.         Recycle();
    19.     }
    20.  
    21.     void Recycle()
    22.     {
    23.         BulletHoleManager.bulletHole.activeHoles.Remove(gameObject);
    24.         ObjectPool.pool.PoolObject(gameObject);
    25.     }
    26. }

    Health.cs - my health script so far, its pretty basic but has a lot of decent features... more to be added as I need them
    Code:  
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class Health : MonoBehaviour
    6. {
    7.     public bool isInvincible = false;
    8.     public float maxHealth = 100.0f;
    9.     public float health = 100.0f;
    10.  
    11.     // my resistance to different damage types
    12.     // you basically want resistances between 0 and 2, where 0 is totally immune to damage type,
    13.     // 1 takes straight damage as in no resistance or weakness and 2 is take double damage
    14.     public Resistance myResistances = new Resistance();
    15.    
    16.     public bool canRegen = false;
    17.     public float regenTick = 2.0f;
    18.     public int regenAmount = 1;
    19.  
    20.     public bool useObjectPooling = false;
    21.     public bool isDead = false;
    22.  
    23.     public List<GameObject> myKillers = new List<GameObject>();
    24.  
    25.     public virtual void ResetMe()
    26.     {
    27.         isDead = false; // make sure its not dead to start
    28.         health = maxHealth;
    29.     }
    30.  
    31.     public virtual void Hit(ProjectileInfo info)
    32.     {
    33.         if (isInvincible)
    34.         {
    35.             return;
    36.         }
    37.  
    38.         if (!isDead)
    39.         {
    40.             int damage = info.damage.amount;
    41.  
    42.             switch (info.damage.type)
    43.             {
    44.                 case DamageType.NORMAL:
    45.                     damage = Mathf.RoundToInt(damage * myResistances.normal);
    46.                     break;
    47.                 case DamageType.FIRE:
    48.                     damage *= Mathf.RoundToInt(damage * myResistances.fire);
    49.                     break;
    50.                 case DamageType.ICE:
    51.                     damage *= Mathf.RoundToInt(damage * myResistances.ice);
    52.                     break;
    53.                 case DamageType.ACID:
    54.                     damage *= Mathf.RoundToInt(damage * myResistances.acid);
    55.                     break;
    56.                 case DamageType.ELECTRIC:
    57.                     damage *= Mathf.RoundToInt(damage * myResistances.electric);
    58.                     break;
    59.                 case DamageType.POISON:
    60.                     damage *= Mathf.RoundToInt(damage * myResistances.poison);
    61.                     break;
    62.                 default:
    63.                     // take straight damage...
    64.                     break;
    65.             }
    66.  
    67.             // if we are hit by someone new, add them to the list of things attacking me
    68.             if (!myKillers.Contains(info.owner))
    69.             {
    70.                 myKillers.Add(info.owner);
    71.             }
    72.  
    73.             health -= damage;            
    74.  
    75.             if (health <= 0)
    76.             {
    77.                 health = 0;
    78.                 isDead = true;
    79.                 Die();
    80.             }
    81.         }
    82.     }
    83.  
    84.     public virtual void Regen()
    85.     {
    86.         if ((health < maxHealth))
    87.         {
    88.             health += regenAmount;
    89.             if (health > maxHealth)
    90.             {
    91.                 health = maxHealth;
    92.             }
    93.         }
    94.     }
    95.  
    96.     public virtual void Die()
    97.     {
    98.         // send any messages to the player script here to tell it it's dead and to stop taking input
    99.         // or any other script you might need to let know that it died
    100.         if (useObjectPooling)
    101.         {
    102.             ObjectPool.pool.PoolObject(gameObject);
    103.         }
    104.         else
    105.         {
    106.             Destroy(gameObject);
    107.         }
    108.     }
    109. }


    The setup is pretty easy. Throw the weapon script on your weapon or empty game object. Create another empty game object and set it's position to where you want the projectiles to come out of (muzzlePoint). Make sure the muzzlePoint object's forward vector points in the direction you want to fire and parent the muzzle to the weapon so it moves with the weapon. Then in your Player script or where ever you poll for player input add a few lines of code:

    Code:  
    1.    // a few variables
    2.     Gun myGun;  // because all gun types are derived from the base gun class, we can cast it as Gun instead of trying to determine the current gun type
    3.     WeaponType myWeaponType; // the current gun's enum weapon type
    4.  
    5.  
    6.     // call this to get the current weapon type, call on pick up, weapon swap... whenever but do it before you can use the gun
    7.     public void GetWeaponScript()
    8.     {
    9.         myGun = GetComponentInChildren<Gun>();
    10.  
    11.         if (myGun) // check if we have a gun script first to avoid errors
    12.         {
    13.             myWeaponType = myGun.typeOfWeapon;
    14.         }
    15.     }
    16.  
    17.  
    18.      // somewhere in your update function just add the code for checking for the fire button
    19.      if (myGun) // check if we have a gun script first to avoid errors
    20.         {
    21.             if (myWeaponType == WeaponType.FULLAUTO)
    22.             {
    23.                 if (Input.GetButton("Fire1"))
    24.                 {
    25.                     myGun.Fire();
    26.                 }
    27.             }
    28.             else
    29.             {
    30.                 if (Input.GetButtonDown("Fire1"))
    31.                 {
    32.                     myGun.Fire();
    33.                 }
    34.             }
    35.         }


    All script files above are in the Novashot_Gun_81313.zip attachment below.
    Well hope the Updates help out someone.... and If not, the older version is still below if need be.









    ***** OLDER STUFF ******

    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.
    Attached Files
    Last edited by novashot; 08-13-2013 at 04:22 PM. Reason: Updated ...Everything


  2. Posts
    427
    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!


  3. Location
    Spring Hill, TN
    Posts
    221
    Quote Originally Posted by gamesurgeon
    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.
    I'm 14 years old and counting.


  4. Posts
    981
    AMAZING!

    But there is no recoil.


  5. Location
    Michigan
    Posts
    201

    rocket... and more

    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.
    Attached Files


  6. Location
    Michigan
    Posts
    201
    Quote Originally Posted by CreativeCoding
    AMAZING!

    But there is no recoil.

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


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

    Pretty awesome.


  8. Location
    Spring Hill, TN
    Posts
    221
    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!
    I'm 14 years old and counting.


  9. Location
    Michigan
    Posts
    201
    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.
    Attached Files


  10. Location
    Michigan
    Posts
    201

    Update

    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/...e_Weapons.html

    Added the updated scripts and prefab packages also.
    Attached Files


  11. Posts
    7
    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.


  12. Posts
    13
    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 for `offsetY' and no extension method `offsetY' of type `MouseLook' could be found (are you missing a using directive or an assembly reference?)"
    ----------------------

    NVM, got it solved by adding those vars to MouseLook
    Last edited by NewOrblivia; 11-16-2010 at 09:21 AM. Reason: Solved


  13. Location
    Michigan
    Posts
    201
    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/WebP...WebPlayer.html

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


  14. Posts
    13
    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).gun Type) {

    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(Pr ojectile).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");
    }


  15. Location
    Michigan
    Posts
    201
    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:

    Code:  
    1.        bulletInfo[0] = damage;
    2.         bulletInfo[1] = impactForce;
    3.         bulletInfo[2] = maxPenetration;
    4.         bulletInfo[3] = maxSpread;
    5.         bulletInfo[4] = spread;
    6.         bulletInfo[5] = bulletSpeed;
    7.  
    8.         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:

    Code:  
    1.            // send a message to the hit object... let it know it was hit
    2.             bulletInfo[0] = ownersName;        // tell hit object who hit them
    3.             bulletInfo[1] = damage.ToString(); // tell them how much damage they recieved
    4.             // send the message
    5.             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:

    Code:  
    1. public void ImHit(string[] info)
    2.     {
    3.        
    4.         if(!dead)
    5.         {
    6.             string myKiller = info[0];
    7.             float damage = float.Parse(info[1]);
    8.            
    9.             //Debug.Log(" I been hit by " + myKiller + " for " + damage + " damage");          
    10.            
    11.             health -= damage; // do some damage
    12.            
    13.             //Debug.Log("My health is now " + health + " / " + maxHealth);
    14.            
    15.             if(health<=0)
    16.             {  
    17.                             health = 0;
    18.                 dead = true;
    19.                 StartCoroutine(Die());
    20.             }
    21.         }
    22.     }

    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


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


  17. Location
    Missouri
    Posts
    211
    The third person view needs some work. Allow the player to aim with the mouse, not just the A and D buttons


  18. Location
    Michigan
    Posts
    201
    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
    Last edited by novashot; 02-27-2011 at 12:24 AM. Reason: Fixed Links


  19. Posts
    1
    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......
    thx before.......


  20. Posts
    15
    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!!

Page 1 of 4 123 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •