- Home /
damage system
so i have a gun script and a custom bullet script does any one know how i can make a damage system like the enemy will have 100 health and not a one shot
this is the gun script //bullet force public float shootForce, upwardForce;
//Gun stats
public float timeBetweenShooting, spread, reloadTime, timeBetweenShots;
public int magazineSize, bulletsPerTap;
public bool allowButtonHold;
int bulletsLeft, bulletsShot;
//Recoil
public Rigidbody playerRb;
public float recoilForce;
//bools
bool shooting, readyToShoot, reloading;
//Reference
public Camera fpsCam;
public Transform attackPoint;
//Graphics
public GameObject muzzleFlash;
public TextMeshProUGUI ammunitionDisplay;
//bug fixing :D
public bool allowInvoke = true;
private void Awake()
{
//make sure magazine is full
bulletsLeft = magazineSize;
readyToShoot = true;
}
private void Update()
{
MyInput();
//Set ammo display, if it exists :D
if (ammunitionDisplay != null)
ammunitionDisplay.SetText(bulletsLeft / bulletsPerTap + " / " + magazineSize / bulletsPerTap);
}
private void MyInput()
{
//Check if allowed to hold down button and take corresponding input
if (allowButtonHold) shooting = Input.GetKey(KeyCode.Mouse0);
else shooting = Input.GetKeyDown(KeyCode.Mouse0);
//Reloading
if (Input.GetKeyDown(KeyCode.R) && bulletsLeft < magazineSize && !reloading) Reload();
//Reload automatically when trying to shoot without ammo
if (readyToShoot && shooting && !reloading && bulletsLeft <= 0) Reload();
//Shooting
if (readyToShoot && shooting && !reloading && bulletsLeft > 0)
{
//Set bullets shot to 0
bulletsShot = 0;
Shoot();
}
}
private void Shoot()
{
readyToShoot = false;
//Find the exact hit position using a raycast
Ray ray = fpsCam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0)); //Just a ray through the middle of your current view
RaycastHit hit;
//check if ray hits something
Vector3 targetPoint;
if (Physics.Raycast(ray, out hit))
targetPoint = hit.point;
else
targetPoint = ray.GetPoint(75); //Just a point far away from the player
//Calculate direction from attackPoint to targetPoint
Vector3 directionWithoutSpread = targetPoint - attackPoint.position;
//Calculate spread
float x = Random.Range(-spread, spread);
float y = Random.Range(-spread, spread);
//Calculate new direction with spread
Vector3 directionWithSpread = directionWithoutSpread + new Vector3(x, y, 0); //Just add spread to last direction
//Instantiate bullet/projectile
GameObject currentBullet = Instantiate(bullet, attackPoint.position, Quaternion.identity); //store instantiated bullet in currentBullet
//Rotate bullet to shoot direction
currentBullet.transform.forward = directionWithSpread.normalized;
//Add forces to bullet
currentBullet.GetComponent<Rigidbody>().AddForce(directionWithSpread.normalized * shootForce, ForceMode.Impulse);
currentBullet.GetComponent<Rigidbody>().AddForce(fpsCam.transform.up * upwardForce, ForceMode.Impulse);
//Instantiate muzzle flash, if you have one
if (muzzleFlash != null)
Instantiate(muzzleFlash, attackPoint.position, Quaternion.identity);
bulletsLeft--;
bulletsShot++;
//Invoke resetShot function (if not already invoked), with your timeBetweenShooting
if (allowInvoke)
{
Invoke("ResetShot", timeBetweenShooting);
allowInvoke = false;
//Add recoil to player (should only be called once)
playerRb.AddForce(-directionWithSpread.normalized * recoilForce, ForceMode.Impulse);
}
//if more than one bulletsPerTap make sure to repeat shoot function
if (bulletsShot < bulletsPerTap && bulletsLeft > 0)
Invoke("Shoot", timeBetweenShots);
}
private void ResetShot()
{
//Allow shooting and invoking again
readyToShoot = true;
allowInvoke = true;
}
private void Reload()
{
reloading = true;
Invoke("ReloadFinished", reloadTime); //Invoke ReloadFinished function with your reloadTime as delay
}
private void ReloadFinished()
{
//Fill magazine
bulletsLeft = magazineSize;
reloading = false;
}
}
this is the custom bullet public class CustomBullet : MonoBehaviour { //Assignables public Rigidbody rb; public GameObject explosion; public LayerMask whatIsEnemies;
//Stats
[Range(0f,1f)]
public float bounciness;
public bool useGravity;
//Damage
public int explosionDamage;
public float explosionRange;
public float explosionForce;
//Lifetime
public int maxCollisions;
public float maxLifetime;
public bool explodeOnTouch = true;
int collisions;
PhysicMaterial physics_mat;
private void Start()
{
Setup();
}
private void Update()
{
//When to explode:
if (collisions > maxCollisions) Explode();
//Count down lifetime
maxLifetime -= Time.deltaTime;
if (maxLifetime <= 0) Explode();
}
private void Explode()
{
//Instantiate explosion
if (explosion != null) Instantiate(explosion, transform.position, Quaternion.identity);
//Check for enemies
Collider[] enemies = Physics.OverlapSphere(transform.position, explosionRange, whatIsEnemies);
for (int i = 0; i < enemies.Length; i++)
{
//Get component of enemy and call Take Damage
//Just an example!
///enemies[i].GetComponent<ShootingAi>().TakeDamage(explosionDamage);
//Add explosion force (if enemy has a rigidbody)
if (enemies[i].GetComponent<Rigidbody>())
enemies[i].GetComponent<Rigidbody>().AddExplosionForce(explosionForce, transform.position, explosionRange);
}
//Add a little delay, just to make sure everything works fine
Invoke("Delay", 0.05f);
}
private void Delay()
{
Destroy(gameObject);
}
private void OnCollisionEnter(Collision collision)
{
//Don't count collisions with other bullets
if (collision.collider.CompareTag("Bullet")) return;
//Count up collisions
collisions++;
//Explode if bullet hits an enemy directly and explodeOnTouch is activated
if (collision.collider.CompareTag("Enemy") && explodeOnTouch) Explode();
}
private void Setup()
{
//Create a new Physic material
physics_mat = new PhysicMaterial();
physics_mat.bounciness = bounciness;
physics_mat.frictionCombine = PhysicMaterialCombine.Minimum;
physics_mat.bounceCombine = PhysicMaterialCombine.Maximum;
//Assign material to collider
GetComponent<SphereCollider>().material = physics_mat;
//Set gravity
rb.useGravity = useGravity;
}
/// Just to visualize the explosion range
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, explosionRange);
}
}
thanks for your time.
Before trying to add more. Have you thought about refactoring your code to make it a little tidier? It may make it easier to work with and implement new features.
For example there is a lot of redundant code in here, there is also a lot of noise. As your code base grows, if it is written like this its going to get harder and harder to work with.
Another thing to mention is that your code should be self documenting:
//Assign material to collider
GetComponent<SphereCollider>().material = physics_mat;
//Set gravity
rb.useGravity = useGravity;
These comments are tautological. If your comments are just repeating what the code literally says then they are not useful. If your code isn't legible enough to be read without comments for basic things then your code isn't readable enough.
Your answer
Follow this Question
Related Questions
Any problem with using real weapons in a FPS game? 0 Answers
Deal damage on collision 2 Answers
how to make bullets apply damage 1 Answer
FPS damage arrow? (raycast shoot) 2 Answers
How to Implement First Shot Accuracy? 2 Answers