- Home /
How do I make my bullet prefab do damage to the enemy?
I'm trying to make a fps and decided to use prefab bullets instead of raycast, But I cant get the bullets to damage the enemy on contact.
Enemy health script
public int EnemyHealth = 20;
public bool EnemyDead = false;
public GameObject EnemyAI;
public GameObject Enemy;
void DamageEnemy(int damageAmmount)
{
EnemyHealth -= damageAmmount;
Enemy.GetComponent<Animator>().Play("Damage1");
Enemy.GetComponent<Animator>().Play("Damage1", -1, 0);
}
void Update()
{
if (EnemyHealth <= 0 && EnemyDead == false)
{
EnemyDead = true;
Enemy.GetComponent<Animator>().Play("Death");
EnemyAI.SetActive(false);
GlobalScore.ScoreValue += 700;
GlobalComplete.EnemyCount += 1;
this.GetComponent<BoxCollider>().enabled = false;
}
}
Bullet script
public Vector3 m_target;
public GameObject collisionExplosion;
public float speed;
void Update()
{
float step = speed * Time.deltaTime;
if (m_target != null)
{
if (transform.position == m_target)
{
explode();
return;
}
transform.position = Vector3.MoveTowards(transform.position, m_target, step);
}
}
public void setTarget(Vector3 target)
{
m_target = target;
}
void explode()
{
if (collisionExplosion != null)
{
GameObject explosion = (GameObject)Instantiate(
collisionExplosion, transform.position, transform.rotation);
Destroy(gameObject);
Destroy(explosion, 1f);
}
}
How do I make the bullet script cause damage to the Enemy health script upon the bullet prefab's collision?
Answer by pete94za · Mar 04, 2020 at 07:49 PM
Create a tag for your enemy, let's say "Enemy", and make sure you assign this tag to the Enemy. Then in your bullet script add this method:
private void OnCollisionEnter(Collision collision)
{
if (collision.transform.tag == "Enemy")
{
// do damage here, for example:
collision.gameObject.GetComponent<Enemy>().TakeDamage(5);
}
}
And in your Enemy Script, create the function:
public void TakeDamage(int damageAmount)
{
health -= damageAmount;
// other stuff you want to happen when enemy takes damage
}
But in order to detect the collisions better, both of these objects should probably have a Rigidbody attached to them (The Enemy and the Bullet).
Sadly it doesn't work, I added a Debug.Log inside of it, but it didn't give me any messages. And if I uncomment the collision.GetComponent<Enemy>().TakeDamage();
it says that Collision doesn't contain a definition for 'GetComponent'.
I edited my answer. ins$$anonymous$$d of collision.GetComponent it should be collision.gameObject.GetComponent and also be sure to actually implement the function in your Enemy script. I just gave you an example of what you could do. But I've now included the TakeDamage function too for you.
HEllo.
REad the OnCollision manual. Be sure you do all necessary things in the editor
Also in the GetComponent part, be sure to change the Enemy() to whatever your Enemy script is called.
Answer by Fragsteel · Mar 04, 2020 at 10:53 PM
The answer from @pete94za will work and is the most direct answer to OP's question. But for future reference, it can help to implement an interface for anything that can take damage. In most games, there are multiple things that can take damage, not just a single "enemy" class. If you're searching for a class like Enemy in GetComponent, then the only way to have a bullet be able to damage multiple kinds of things is to do different checks for every kind of potential object, eg. GetComponent<Crate>()
, GetComponent<Window>()
, etc. (it can be a tad simpler using inheritance, but you get the point and interfaces are still better)
Instead, such interface could look like:
public interface IDamageable
{
void TakeDamage(float damage);
}
Then, any class that should be damageable by the bullet (or anything else that does damage) can implement IDamageable, and have a method like TakeDamage(float damage). Each class like Enemy, Window, Crate, etc. can write that method differently, but implementing that interface guarantees that the method exists. It could look like:
public class Enemy : MonoBehaviour, IDamageable
{
float hp = 10;
void IDamageable.TakeDamage(float damage)
{
hp -= damage;
Debug.Log(gameObject.name + " took " + damage + " damage.");
if(hp <= 0)
{
Destroy(gameObject);
}
}
}
Then in your bullet, you do:
IDamageable damageable = collision.gameObject.GetComponent();
if(damageable != null)
{
damageable.TakeDamage(5);
}
That will work on any class that implements IDamageable, regardless of its actual type.
Answer by Natrx · Aug 22, 2020 at 03:33 PM
If the enemy is in a gameobject then do: gameObject.GetComponentInParent(typeof(Enemy)) as Enemy; or you can use my script here: using System.Collections; using System.Collections.Generic; using UnityEngine;
public class Bullet : MonoBehaviour {
public float speed = 20f;
public int damage = 10;
public Rigidbody2D rb;
public GameObject Enemy;
public GameObject impactEffect;
// Use this for initialization
void Start () {
rb.velocity = transform.right * speed;
}
void OnTriggerEnter2D (Collider2D hitInfo)
{
if(hitInfo.CompareTag("Enemy")){
Enemy enemy = hitInfo.transform.gameObject.GetComponentInParent(typeof(Enemy)) as Enemy;
if (enemy != null)
{
enemy.TakeDamage(damage);
}
Instantiate(impactEffect, transform.position, transform.rotation);
Destroy(gameObject);
}
}
}
Your answer
![](https://koobas.hobune.stream/wayback/20220612224404im_/https://answers.unity.com/themes/thub/images/avi.jpg)