Hi Everyone,
I’ve hit a problem that I need to fix before I can go any further.
If player collides with enemies without a RigidBody2D, player damage function works fine (player takes damage).
If I add a RigidBody2D to the enemy, the Take Damage function stops working partially — some of the function is still triggered (such as a “damage blink”).
Here’s a clip of this behavior.
- The first enemy has a rigidbody2d, the second one doesn’t.
- Notice how on the first enemy, when colliding, the health bar (red bar) does not go down. But on the second enemy, it does go down.
- BUT, in both instances, the damage blinking is working. So, just the “Take Damage” portion isn’t.
Here’s the Monster Damage code, followed by the PlayerHealth code…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonsterDamage : MonoBehaviour
{
public int damage; // declare a public integer called damage
PlayerHealth ph; // declare the PlayerHealth for assignment
void Awake()
{
ph = GameObject.FindWithTag("Player").GetComponent<PlayerHealth>(); //we assigned the ph field from above
}
void start()
{
damage = 1; // set the damage for this monster
}
private void OnCollisionEnter2D(Collision2D collision) // name of this private void function, it's a collision event
{
if (ph.noDamage == false) // if the "NoDamage" state from PlayerHealth is false...
{
if (collision.collider.gameObject.tag == "Player") // and collision with "Player"
{
ph.TakeDamage(damage); // Do the TakeDamage function
return; // return
}
}
else if (ph.noDamage == true) // if the "NoDamage" state is true
{
ph.TakeDamage(0); // 0 damage is taken
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerHealth : MonoBehaviour
{
PlayerMovement pm; // declare the playermovement script
HealthBar hb; // this script needs to modify the health bar
SpriteRenderer sprite; // same
[Range (0, 50)] public int maxHealth = 5; // declare and set an integer called Max Health to 5
public int currentHealth; // declare a public integer for what we'll call Current Health
public bool noDamage; // a public boolean called No Damage
void Awake()
{
pm = GetComponent<PlayerMovement>(); // define what/where the playermovement script is
hb = GameObject.FindWithTag("UIHealth").GetComponent<HealthBar>(); // same
sprite = GetComponent<SpriteRenderer>(); // and again
}
void Start()
{
noDamage = false; // No Damage is set to false at start
currentHealth = maxHealth; // Current Health is set to whatever the max health is defined as above
hb.SetMaxHealth(maxHealth); // Access the Health Bar script, and set the function within it, SetMaxHealth, with to our Max Health integer from this script.
}
public void TakeDamage(int damage) // a function called TakeDamage
{
if (noDamage == false) // for starters, only perform this function is No Damage is currently false
{
currentHealth -= damage; // current health will be reduced by whatever damage is sent over (Monster Damage script will send this integer, or Spike Damage, or Rock Damage..)
StartCoroutine(NoDamage()); // start the NoDamage function above
StartCoroutine(Blink()); // start the Blink function above
hb.SetHealth(currentHealth); // At the end, make sure to update the on screen Health Bar with whatever our Current Health is
//function is complete
}
}
public IEnumerator NoDamage() // a public function caled NoDamage. Player cannot take damage with this function is running
{
//below instructions happen in order
noDamage = true; // change the noDamage bool to true. Some actions will check for that bool.
yield return new WaitForSeconds(1.7f); // we are going to wait for 1 and almost 3 quarters of a second
noDamage = false; // return the noDamage bool to false
}
public IEnumerator Blink() // a public function called Blink
{
for (int i = 0; i < 10; i++) // this is a for-loop,
{
sprite.enabled = false; // sprite renderer is disabled (because enabled parameter is set to false)
yield return new WaitForSeconds(0.08f); // wait for 8/100 of a second
sprite.enabled = true; // reenable the sprite renderer
yield return new WaitForSeconds(0.08f); // wait again.... after this, the code is complete (unless it hasn't finished the loop)
}
}
}