Instantiated object affecting variables on the object that instantiated it

I have a GameObject “gun” with a script on it instantiate a projectile with a ‘health’, however it appears to be treating health as a global variable and causing the gun to shoot bullets that all share the same health pool. The initial health is stored on the gun itself, so that all bullets shot from the gun have this as their initial health. Instead, the health on the gun goes down as well.

The health is supposed to act as a piercing effect, allowing a bullet to go through a certain number of colliders before destroying itself.

Gun Script

[System.Serializable]  
public class Weapon 
{  
	public int damage;   
	public int health;  
	//etc, more public variables here  
}  

void public class WepSys  
{  
	public Weapon wep;  
	void Shoot ()
	{
		GameObject shot = (GameObject) Instantiate(object, position, rotation);
		shot.GetComponent<ProjectileMover> ().wep = wep;
		shot.GetComponent<ProjectileMover> ().iniVel = GetComponent<Rigidbody>().velocity;
	}
}

ProjectileMover Script

public class ProjectileMover : MonoBehaviour  
{ 
	public Weapon wep;  
	void OnTriggerEnter( Collider other )  
	{  
		if (wep.health > 0)  
		{  
			wep.health--;  
		}  
		else
		{  
			Destroy (this);
		}
	}
}

Weapon is a class. Classes are reference types. In this line:

shot.GetComponent<ProjectileMover> ().wep = wep;

you assign the same Weapon instance to the newly instantiated object. So both classes (“WepSys” as well as your "ProjectileMover ") will reference the same Weapon instance. If you change something inside the Weapon instance, that change will be “seen” by every class that references the same object.

You might want to create a copy of your Weapon instance. For this you might want to add a “copy constructor”. When you add a copy constructor you also need to add a normal one (parameterless):

[System.Serializable]  
public class Weapon 
{  
    public int damage;
    public int health;
    public Weapon() // parameterless constructor
    {
    }
    public Weapon(Weapon aSource) // copy constructor
    {
        damage = aSource.damage;
        health = aSource.health;
        // [ ... ]
    }
    // [ ... ]
}  

Now instead of assigning the same instance, you will assign a copy of the instance:

shot.GetComponent<ProjectileMover> ().wep = new Weapon(wep);