0
\$\begingroup\$

I have a melee enemy tagged as enemy. enemy has two coliders: a capsule(physics) and a sphere(for attacking player in radius and istrigger) and a particlesystem, enemy has enemyhealth script attached.

Similarly, bullet has capsule collider and set istrigger, I've attached enemyhealth script to bullet as enemy sphere and bullet capsule are triggers (bullet doesn't have any particle system need fix for this too without raycast), bullets are destroyed on colliding with enemy but doesn't damage the enemy.

script used for enemy health

using UnityEngine;
using System.Collections;

public class enemyhealth : MonoBehaviour {
  public int health = 40;
  public int current;
  //public int score = 10;
  public AudioSource deathclip;
  public ParticleSystem death;
  CapsuleCollider Collider;
  bool dead;
  // Use this for initialization
  void Start () 
  {
    deathclip = GetComponent<AudioSource> (); 
    Collider = GetComponent<CapsuleCollider> ();
    death = GetComponentInChildren <ParticleSystem> ();
    current = health;
    dead = false;
  }

  void Update()
  {}

  public void Takedamage (int amount )
  {
    if (dead)
      return;
    current -= amount;

    if (current <=0)
      die ();
  }

  void die () 
  {  
    //GetComponent<NavMeshAgent> ().enabled = false;
    dead = true;
    Collider.isTrigger = true;
    deathclip.Play ();
    death.transform.parent = null;
    death.Play ();
    Destroy(death.gameObject);
    Destroy(gameObject);
  }
}

script used for bullet

using UnityEngine;
using System.Collections;

public class mover : MonoBehaviour {
  public float speed;
  public int damage = 10;
  enemyhealth Enemyhealth;
  GameObject ENEMY;
  bool enemyinrange;

  // Use this for initialization
  void Awake () {
    GetComponent<Rigidbody>().velocity = transform.forward*speed;
    Enemyhealth = GetComponent<enemyhealth> ();
    ENEMY = GameObject.FindGameObjectWithTag ("enemy");
  }
  void OnTriggerEnter(Collider other)
  {
    if(other.gameObject == ENEMY && Enemyhealth.currenthealth >=0)
      enemyinrange=true;

    //Destroy(gameObject);
  } 
  void OnTriggerExit(Collider other)
  {
    if (other.gameObject == ENEMY)
      enemyinrange = false;
  }
  void Damage()
  {
    Enemyhealth.Takedamage (damage);
  }

  // Update is called once per frame
  void Update () 
  {
    if (enemyinrange) 
        Damage ();
  }
}
\$\endgroup\$
14
  • \$\begingroup\$ Both scripts are attached to the same GameObject? \$\endgroup\$ Jan 8 '16 at 17:04
  • \$\begingroup\$ no,enemyhealth to enemy and mover to bullet. \$\endgroup\$
    – sparkblack
    Jan 8 '16 at 17:06
  • \$\begingroup\$ But you are using Enemyhealth = GetComponent<enemyhealth> (); in mover that attached to bullet. Simple GetComponent is use to get components attached to the same GameObject \$\endgroup\$ Jan 8 '16 at 17:08
  • \$\begingroup\$ Move this line after ENEMY initialization in Awake and modify it as Enemyhealth = ENEMY.GetComponent<enemyhealth> ();. Let me know if it works then I'll write a complete answer \$\endgroup\$ Jan 8 '16 at 17:09
  • \$\begingroup\$ actually,i got null reference exception if i dont attach the script mover to bullet which i dont want, \$\endgroup\$
    – sparkblack
    Jan 8 '16 at 17:11
1
\$\begingroup\$

1) Don't put these lines of code in Awake(). When the script wakes up, it has only just been fired.

2) Switch their order and use ENEMY.GetComponent()

 void OnTriggerEnter(Collider other)
 {
     //if you have more than one enemy, this is the only way to hit the correct one
     ENEMY = other.gameObject;
     Enemyhealth = ENEMY.GetComponent<enemyhealth> ();
     enemyinrange=true;
 }
\$\endgroup\$
0
\$\begingroup\$

Oh, Draco18s is right. Here is your modified whole script. Replace it.

using UnityEngine;
 using System.Collections;

 public class mover : MonoBehaviour {
     public float speed;
     public int damage = 10;
     enemyhealth Enemyhealth;
     GameObject ENEMY;
     bool enemyinrange;

     // Use this for initialization
     void Awake () {

         GetComponent<Rigidbody>().velocity = transform.forward*speed;



     }
     void OnTriggerEnter(Collider other)
     {
         if(other.gameObject.tag == "enemy")
         {
             GameObject enemyNew = other.gameObject;
             enemyhealth enemyHealthNew = enemyNew.GetComponent<enemyhealth> ();
             if (enemyHealthNew.currenthealth >=0)
                 enemyHealthNew.Takedamage (damage);
         }

         Destroy(gameObject);


     } 

} 
\$\endgroup\$
12
  • \$\begingroup\$ You can't comapre other.gameobject with ENEMY, as ENEMY will be null by the time that comparison is run, thus always false, and therefore never set. \$\endgroup\$ Jan 8 '16 at 17:34
  • \$\begingroup\$ Oh man, I thought to change that.. :) \$\endgroup\$ Jan 8 '16 at 17:35
  • \$\begingroup\$ There's a few other caveats that may depend on the asker's goals (you destroy the bullet as soon as it hits anything, maybe he wants it to penetrate). There's also no point in saving the reference to a class field if the bullet only does damage once. Etc. \$\endgroup\$ Jan 8 '16 at 17:36
  • \$\begingroup\$ He is a noob according to him, so I'm going this way :) \$\endgroup\$ Jan 8 '16 at 17:38
  • 1
    \$\begingroup\$ Missed that, was just looking for any subtle point of failure. @sparkblack Looks like you're going to have to insert some debug.log() statements to locate what line of code isn't doing what you expect it to. \$\endgroup\$ Jan 8 '16 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.