Bullets doesnt do any damage
I have an 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 is trigger,ive attached enemyhealth script to bullet as enemy sphere and bullet capsule are triggers,(bullet doent have any particle system need fix for this too without raycast),bullets are destroyed on colliding with enemy but doent damage the enemy.
script used for enemy health using UnityEngine; using System.Collections;
public class enemyhealth : MonoBehaviour {
public int health = 40;
public int currenthealth;
//public int score = 10;
public AudioSource deathclip;
ParticleSystem death;
//CapsuleCollider Collider;
bool dead;
// Use this for initialization
void Start ()
{
deathclip = GetComponent<AudioSource> ();
//Collider = GetComponent<CapsuleCollider> ();
death = GetComponentInChildren <ParticleSystem> ();
currenthealth = health;
dead = false;
}
void Update()
{
}
public void Takedamage(int amount )
{
if (dead)
return;
currenthealth -= amount;
if
(currenthealth <=0)
{
die ();
}
}
// Up date is called once per frame
void die ()
{
//GetComponent<NavMeshAgent> ().enabled = false;
dead = true;
Destroy(gameObject);
//Collider.isTrigger = true;
//deathclip.Play ();
//death.Play ();
}
}
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 ();
}
}
}
Thanks
Hi Sparkblack, you might consider "accepting" one of the answers (either $$anonymous$$ung$$anonymous$$ras' or $$anonymous$$e) as the correct answer ("Accept"-button at the bottom of the answer) so that other users can see that the problem is solved and don't need to come up with additional solutions :) (Also, it gives us $$anonymous$$arma, we greedy bastards <3 :) ) Cheers & good luck with your project! :)
Answer by Sparkblack · Jan 09, 2016 at 10:49 AM
Thanks again hyperi0n ,figured making the check while firing bullet was the problem.now i understand why gameobject == ENEMY gives null reference exception,checked foe tag "enemy" works fine now.
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.current >= 0)
enemyHealthNew.Takedamage (damage);
}
Destroy(gameObject);
}
}
Great :) Glad that it works! :)
Forgive me for commenting yet again, and for perhaps co$$anonymous$$g across like an obsessive $$anonymous$$cher -- I do tutoring and sometimes I just can't help it :D
Just as a kind of bottom line, not immediately connected to your question: Always try to keep objects and components together that belong together: enemyhealth should DEFINITELY be part of the respective enemy game object and nothing else, especially not a bullet. Really think about what things belong together, and keep them together, isolated as much as possible from other game objects. Think about a group of small islands connected by shipping lanes (e.g. the bullet would be one island, the enemy another, the player yet another..). Everything that is important for one island should BE ON THAT ISLAND ( = attached to the correct game object) and the island should also be able to function on its own if all other islands were gone. When islands have to interact with each other, you have to send a ship from one island to the next ( = call a function on a script on another object, send a message etc.) and then you really have to think very well on "what should be on that ship", = what information you need to send across. Then the ship arrives at the destination island's harbour, is unloaded (the information is received) and then the destination island handles it according to it's own way (through its own scripts).
This may mean some extra hard thinking and preparation when you first start, but trust me, in the long run it will help you a lot and really be necessary if you want to make a complex game. If you are doing a project where you have enemies and bullets, trust me, this kind of clear and well thought-through structure will be absolutely essential. Good luck with your project! :)
Answer by hyperi0n · Jan 08, 2016 at 02:24 PM
Disclaimer: I am something of a noob in general and VERY MUCH a noob with c# :) But here goes: I am assuming that the enemyhealth is attached to the ENEMY game object, right? In the bullet script, shouldn't Lines 16 and 18 be switched around and modified so that the variable Enemyhealth refers to the "enemyhealth" script component of the "ENEMY" object?
ENEMY = GameObject.FindGameObjectWithTag ("enemy");
Enemyhealth = ENEMY.GetComponent<enemyhealth> ();
I hope this goes in the right direction; please forgive me if I'm mistaken :)
Thanks for your response hyperi0n,I am a noob too and no it doesnot solve my problem,i also have attack script attached to enemy which uses enemyhealth script and it conflicts with each other,and i forgot to mention the bullet is a prefab,waiting for your answers friends,banging my head for almost a day and half with no improvement,enemy walks straight towards the player unharmed. Thaks again.
Ok, I thiiink I solved it.
So here's what you have to do, the most important thing is that the "enemyhealth" script should be attached to the ENE$$anonymous$$Y and not the bullet. This will make further work on the game much easier: always try to keep things together that BELONG together (the bullet itself really has nothing to do with the enemy).
Then you should replace the "mover" script on the bullet with the following much shorter & simpler "BulletScript" script:
[SEE UPDATE BELOW FOR I$$anonymous$$PROVED CODE]
The big difference to the old script is that when the bullet enters the enemy's collider, it immediately applies damage and is then destroyed. Before, your bullet was passing through the enemy and dealing damage every frame it was "inside" the enemy, i think, right? This way should be much easier.
In terms of code the most important change is the same thing i mentioned in my original answer: the "enemyhealth" script SHOULD be attached to the "ENE$$anonymous$$Y" object. Therefore, the BulletScript also has to have it's references set up correctly: FIRST say which object is meant by "ENE$$anonymous$$Y" and SECOND tell the script that Enemyhealth is a component of the ENE$$anonymous$$Y object (lines 17 & 18). I tested this and it works for me. If there still are any problems, they most likely are with other scripts or perhaps the way the colliders are set up..
//EDIT: small correction to the code
UPDATE:
Sorry for all the spam. I have modified the Code again to make it $$anonymous$$UCH more useful:
using UnityEngine;
using System.Collections;
public class BulletScript : $$anonymous$$onoBehaviour {
public float speed;
public int damage = 10;
enemyhealth Enemyhealth;
GameObject ENE$$anonymous$$Y;
// Use this for initialization
void Awake () {
//give the bullet starting speed
GetComponent<Rigidbody>().velocity = transform.forward*speed;
}
void OnTriggerEnter(Collider other)
{
//When "starting to collide" with the enenmy, apply damage once and immediately destroy the bullet.
if (other.gameObject.tag == "enemy")
{
//if the collided object has the tag "enemy", then tell this bullet script that THAT object is the enemy to damage.
Enemyhealth = other.gameObject.GetComponent<enemyhealth>();
Enemyhealth.Takedamage(damage);
Destroy(gameObject);
}
}
}
What happens now is that when the bullet collides with a collider, it checks if it is an enemy (via that object's tag). If the collided object IS an enemy, then tell the bullet script to damage THAT specific enemy it has collided with (by identifying the object that belongs to the collider and then "targeting" the "enemyhealth" script belonging to THAT game object.
What this means is that you can now have AS $$anonymous$$ANY ENE$$anonymous$$IES AS YOU WANT, as opposed to only a single one. $$anonymous$$uch better, no? :) If you have any more questions, ask away!
Note: It still is important that the "enemyhealth" is attached to the ENE$$anonymous$$Y object! :)
Answer by KungKras · Jan 10, 2016 at 07:14 AM
How many enemies are in your scene? It looks the the "ENEMY" reference in your mover script uses FindGameObjectWithtag, then finds one such object in the scene, not all.
Also, when you use GetComponent in mover (which you said is the script on your bullets), you get the EnemyHealth on your bullet, not your enemy. So when enemyinrange = true, you call Damage which has a refecence to your bullet's EnemyHealth making your bullet take the damage.
What you should do when the bullet hits an enemy is something like this.
void OnTriggerEnter(Collider other) {
if(other.tag == "enemy") {
if(other.gameObject.GetComponent<enemyhealth>() != null) {
other.gameObject.GetComponent<enemyhealth>().Takedamage(damageAmount);
}
}
}
Your answer
Follow this Question
Related Questions
Having troubles changing my players speed on collision 0 Answers
Start Finish Timer 0 Answers