Hi I have a problem with those two scripts. The Sword script triggers when its PolygonCollider2D hits BoxCollider2D of the Enemy and it triggers damageImage.color = flashColour;, but it doesn’t make currentHealth shrink. Maybe some fresh look will help?
EnemyHealth
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class EnemyHealth : MonoBehaviour {
public int startingHealth = 10;
public int currentHealthEnemy;
public Image damageImage;
public AudioClip deathClip;
public float flashSpeed = 5f;
public Color flashColour = new Color(1f, 0f, 0f, 0.1f);
public int scoreValue = 10;
Animator anim;
AudioSource enemyAudio;
ParticleSystem hitParticles;
BoxCollider2D boxCollider2D;
PolygonCollider2D polygonCollider2D;
public Sword sword;
enemy enemyMobility;
bool isDead;
bool damaged;
void Awake ()
{
//Seeting up the references
sword = GetComponent <PolygonCollider2D>;
anim = GetComponent <Animator> ();
enemyAudio = GetComponent <AudioSource> ();
hitParticles = GetComponentInChildren <ParticleSystem>();
boxCollider2D = GetComponent <BoxCollider2D> ();
polygonCollider2D = sword.GetComponent <PolygonCollider2D>();
//setting up initial health
currentHealthEnemy = startingHealth;
}
void OnTriggerEnter2D(Collider2D other)
{
if(other.name== "sword")
{
damageImage.color = flashColour;
}
else{
return;
}
}
void Start()
{
if (polygonCollider2D.isTrigger == true){
GameObject go = GameObject.FindWithTag("DamageImage");
damageImage = go.GetComponent<Image>();
}
else{
return;
}
}
void Update()
{
//if the enemy has just been damaged...
if(damaged)
{
damageImage.color = flashColour;
}
else
{
damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
}
damaged = false;
}
public void TakeDamage (int amount)
{
damaged = true; //błyskanie
if(!isDead)
{
return;
}
enemyAudio.Play ();
currentHealthEnemy -= amount;
if(currentHealthEnemy <= 0)
{
Death ();
}
}
void Death ()
{
isDead = true;
//boxCollider2D.isTrigger = true;
anim.SetTrigger ("enemyDead");
enemyAudio.clip = deathClip;
enemyAudio.Play ();
Destroy (this.gameObject);
}
}
Sword:
using UnityEngine;
using System.Collections;
public class Sword : MonoBehaviour {
Animator anim;
GameObject enemy;
EnemyHealth enemyHealth;
ScoreManager scoreManager;
//public int amount = 100;
bool enemyInRange;
public int attackDamage = 10;
void Awake()
{
anim = enemy.GetComponent<Animator>();
enemy = GameObject.FindGameObjectWithTag ("Enemy");
enemyHealth = enemy.GetComponent<EnemyHealth>();
}
void OnTriggerEnter2D(Collider2D enemy)
{
if(enemy.tag== "Enemy")
{
//Destroy (enemy.gameObject);
enemyInRange = true;
}
}
void OnTriggerExit2D (Collider2D enemy)
{
if(enemy.name == "Enemy")
{
enemyInRange = false;
}
}
void Update ()
{
//if the enemy is in range and this enemy is alive...
if (enemyInRange)
{
Attack();
}
//if the enemy has zero or less health///
if (enemyHealth.currentHealthEnemy <= 0)
{
//tell the animator that enemy is dead
anim.SetTrigger ("enemyDead");
}
}
void Attack()
{
//if the enemy has health to lose///
if (enemyHealth.currentHealthEnemy > 0 && enemyInRange)
{
//damage the enemy
enemyHealth.TakeDamage (attackDamage);
}
}
}
For now, I have this error:
cannot convert method group ‘GetComponent’ to non-delegate type ‘Sword’ consider using parentheses to invoke the method.
I have no idea what that error means.
Please help:)
I changed it, but there is an error, which occured before:
UnassignedReferenceException: The variable sword of EnemyHealth has not been assigned. You probably need to assign the sword variable of the EnemyHealth script in the inspector.
Of course I made an assignement in the inspector, but I keep getting this error when both colliders touch themselves.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class EnemyHealth : MonoBehaviour {
public int startingHealth = 10;
public int currentHealthEnemy;
public Image damageImage;
public AudioClip deathClip;
public float flashSpeed = 5f;
public Color flashColour = new Color(1f, 0f, 0f, 0.1f);
public int scoreValue = 10;
Animator anim;
AudioSource enemyAudio;
ParticleSystem hitParticles;
BoxCollider2D boxCollider2D;
public PolygonCollider2D sword;
// public Sword sword;
PolygonCollider2D polygonCollider2D;
enemy enemyMobility;
bool isDead;
bool damaged;
void Awake ()
{
//Seeting up the references
//sword = GetComponent <PolygonCollider2D>;
anim = GetComponent <Animator> ();
enemyAudio = GetComponent <AudioSource> ();
hitParticles = GetComponentInChildren <ParticleSystem>();
boxCollider2D = GetComponent <BoxCollider2D> ();
polygonCollider2D = sword.GetComponent <PolygonCollider2D>();
//setting up initial health
currentHealthEnemy = startingHealth;
}
(...)
}
Unfortunately, it doesnt work. They are colliding, but right now the blinking of a screen (damageImage.color=flashColour;) is not working as well, so objects are colliding, but there is some problem with EnemyHealth script.
I guess I should put something in this condition in EnemyHealth script:
To be clear: Sword is a child of a Player object and it’s PolygonCollider2D is getting enabled in an animation. Maybe that’s why the code is not working?
If Sword object is not assigned in the inspector, the OnTriggerEnter2D method is running, but only damageImage.color = flashColour;
works. In this case, when I run the game the EnemyHealth script is automatically being unchecked by Unity.
When I assign the Sword object in inspector, then the EnemyHealth script is checked, but the damageImage.color=flashColour; is not working.
In both cases, when I put Destroy (this.gameObject); in OnTriggerEnter2D method, it destroys the object, so colliders are working.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class EnemyHealth : MonoBehaviour {
public int startingHealth = 10;
public int currentHealthEnemy;
public Image damageImage;
public AudioClip deathClip;
public float flashSpeed = 5f;
public Color flashColour = new Color(1f, 0f, 0f, 0.1f);
public int scoreValue = 10;
Animator anim;
AudioSource enemyAudio;
ParticleSystem hitParticles;
BoxCollider2D boxCollider2D;
public Sword sword;
PolygonCollider2D polygonCollider2D;
GameObject enemy;
bool isDead;
bool damaged;
void Awake ()
{
//Seeting up the references
enemy = GameObject.FindGameObjectWithTag ("Enemy");
boxCollider2D = GetComponent <BoxCollider2D> ();
polygonCollider2D = sword.GetComponent <PolygonCollider2D>();
anim = GetComponent <Animator> ();
enemyAudio = GetComponent <AudioSource> ();
hitParticles = GetComponentInChildren <ParticleSystem>();
//setting up initial health
currentHealthEnemy = startingHealth;
}
void OnTriggerEnter2D(Collider2D other)
{
if(other.name== "sword")
{
damageImage.color = flashColour;
damaged=true;
//Destroy (this.gameObject);
}
else{
return;
}
}
void Start()
{
if (boxCollider2D.isTrigger == true){
GameObject go = GameObject.FindWithTag("DamageImage");
damageImage = go.GetComponent<Image>();
}
else{
return;
}
}
void Update()
{
//if the enemy has just been damaged...
if(damaged)
{
damageImage.color = flashColour;
}
else
{
damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
}
damaged = false;
}
public void TakeDamage (int amount)
{
damaged = true; //błyskanie
currentHealthEnemy -= amount;
/*if(!isDead)
{
return;
}*/
enemyAudio.Play ();
if(currentHealthEnemy <= 0 && isDead)
{
Death ();
}
}
void Death ()
{
isDead = true;
//boxCollider2D.isTrigger = true;
anim.SetTrigger ("enemyDead");
enemyAudio.clip = deathClip;
enemyAudio.Play ();
Destroy (enemy.gameObject);
}
}
Sword:
using UnityEngine;
using System.Collections;
public class Sword : MonoBehaviour {
Animator anim;
GameObject enemy;
EnemyHealth enemyHealth;
ScoreManager scoreManager;
bool enemyInRange;
public int attackDamage = 10;
void Awake()
{
enemy = GameObject.FindGameObjectWithTag ("Enemy");
enemyHealth = enemy.GetComponent<EnemyHealth>();
anim = enemy.GetComponent<Animator>();
}
void OnTriggerEnter2D(Collider2D enemy)
{
if(enemy.tag== "Enemy")
{
enemyInRange = true;
}
}
void OnTriggerExit2D (Collider2D enemy)
{
if(enemy.name == "Enemy")
{
enemyInRange = false;
}
}
void Update ()
{
//if the enemy is in range and this enemy is alive...
if (enemyInRange)
{
Attack();
}
//if the enemy has zero or less health///
if (enemyHealth.currentHealthEnemy <= 0)
{
//tell the animator that enemy is dead
anim.SetTrigger ("enemyDead");
}
}
public void Attack()
{
//if the enemy has health to lose///
if (enemyHealth.currentHealthEnemy >= 0)
{
//damage the enemy
enemyHealth.TakeDamage (attackDamage);
}
}
}
Also, I’m getting
“NullReferenceException: Object reference not set to an instance of an object”
on “polygonCollider2D = sword.GetComponent ();” in EnemyHealth
and on
public void Attack()
{
//if the enemy has health to lose///
if (enemyHealth.currentHealthEnemy >= 0)
The Enemy object is presented on a screen at the same time Player with Sword object (when game starts, they are already on a screen). Enemy is tagged as Enemy and has Enemy Health Script attached to it.
If I don’t attach any object in Inspector to the Enemy Health (Sword), then when game starts, it is disabled. When I attach object Sword, it starts checked.
Sword object is checked as visible all the time, but it’s Polygon Collider 2D is being enabled in Animator. Maybe this is a problem? I am struggling with script-animator triggers right now, so maybe animations are preventing the script Sword and EnemyHealth from running properly?
I moved
polygonCollider2D = sword.GetComponent ();
from Awake() to Update()
but there is the same error.
I put this line of code where it was before, and I run the game again. EnemyHealth.currenthealthEnemy is shrinking now, as the sword collides with it.
Now I have to learn how to make trigger “anim.SetTrigger (“enemyDead”);” from void Death() work, because “Destroy(enemy.gameObject);” that is present in a code after the anim.SetTrigger doesn’t run. When it is before SetTrigger, it works.
Thank you very much for helping me. I appreciate it.
PS: The bad thing is, I don’t know what was the problem here.
It was a while, and the problem still occurs.
When the Sword collides with Enemy object, everything works fine.
But when it comes to a prefab made of the Enemy object, the health parameter is not shrinking, like the sword collider is not colliding with enemyprefab object (but it is, there is a screen light blinking and particles system working).
I made sure that I find every object with tag, not the name (because of “clone” in prefab names). I can’t find the fault in code (or maybe the problem is somewhere else?)
This is the sword script:
using UnityEngine;
using System.Collections;
public class Sword : MonoBehaviour {
Animator anim;
GameObject enemy;
EnemyHealth enemyHealth;
ScoreManager scoreManager;
//public int amount = 100;
bool enemyInRange;
public int attackDamage = 10;
void Awake()
{
enemy = GameObject.FindGameObjectWithTag ("Enemy").gameObject;
enemyHealth = enemy.GetComponent<EnemyHealth>();
anim = enemy.GetComponent<Animator>();
}
void OnTriggerEnter2D(Collider2D enemy)
{
if(enemy.tag== "Enemy")
{
//Destroy (enemy.gameObject);
enemyInRange = true;
}
}
void OnTriggerExit2D (Collider2D enemy)
{
if(enemy.tag == "Enemy")
{
enemyInRange = false;
}
}
void Update ()
{
//if the enemy is in range and this enemy is alive...
if (enemyInRange)
{
Attack();
}
/*
//if the enemy has zero or less health///
if (enemyHealth.currentHealthEnemy <= 0)
{
//tell the animator that enemy is dead
anim.SetTrigger ("enemyDead");
}*/
}
public void Attack()
{
//if the enemy has health to lose///
if (enemyHealth.currentHealthEnemy >= 0)
{
//damage the enemy
enemyHealth.TakeDamage (attackDamage);
}
else {
return;
}
}
}
I tried to move everything from Awake() to Update(), as sword script should find references to enemy clone objects (prefabs) as they are spawning, but when I do it, nothing is spawning any more. I don’t get eny errors and I have no idea why it is happening.
The EnemyHealth script:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class EnemyHealth : MonoBehaviour {
public int startingHealth = 10;
public int currentHealthEnemy;
public Image damageImage;
public AudioClip deathClip;
public float flashSpeed = 5f;
public Color flashColour = new Color(1f, 0f, 0f, 0.1f);
public int scoreValue = 10;
AnimationClip clip;
Animator anim;
AudioSource enemyAudio;
public GameObject hitParticles;
BoxCollider2D boxCollider2D;
//public Sword sword;
public Transform sword;
PolygonCollider2D polygonCollider2D;
// public Enemy enemy;
//enemy enemyMobility;
GameObject enemy;
bool isDead;
bool damaged;
private Animator animator;
void Awake ()
{
//Seeting up the references
//sword = GetComponent <PolygonCollider2D>;
enemy = GameObject.FindGameObjectWithTag ("Enemy");
boxCollider2D = GetComponent <BoxCollider2D> ();
currentHealthEnemy = startingHealth;
anim = GetComponent <Animator> (); //można przenieść do start()
enemyAudio = GetComponent <AudioSource> ();
//hitParticles = GetComponentInChildren <ParticleSystem>();
}
void OnTriggerEnter2D(Collider2D other)
{
if(other.tag== "Sword")
{
polygonCollider2D = sword.GetComponent <PolygonCollider2D>();
damageImage.color = flashColour;
damaged=true;
Instantiate (hitParticles, enemy.transform.position,Quaternion.Euler(0, 180,0 ));
//Destroy (this.gameObject);
//return;
}
else{
return;
}
}
void Start()
{
//setting up initial health
sword = GameObject.FindWithTag("Sword").transform;
Debug.Log(enemy);
Debug.Log(this);
if (boxCollider2D.isTrigger == true){
GameObject go = GameObject.FindWithTag("DamageImage");
damageImage = go.GetComponent<Image>();
isDead = false;
}
else{
return;
}
}
void Update()
{
//if the enemy has just been damaged...
if(damaged)
{
damageImage.color = flashColour;
}
else
{
damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
}
damaged = false;
}
public void TakeDamage (int amount)
{
damaged = true; //błyskanie
currentHealthEnemy -= amount;
enemyAudio.Play ();
if(currentHealthEnemy <= 0 && !isDead)
{
Death ();
}
}
void Death ()
{
isDead = true;
//boxCollider2D.isTrigger = true;
// Animation.Play(clip.name);
anim.SetTrigger ("enemyDead");
//transform.GetComponent<Animation>().Play("enemyDead");
enemyAudio.clip = deathClip;
enemyAudio.Play ();
Destroy (this.gameObject);
}
/*
public Animator GetAnimator()
{
return animator;
}*/
}
Is there only one enemy and that’s the only enemy that will ever exist and exists at the start of the scene?
Is that how lines 18 and 20 are always the correct references?