Code Problem

using UnityEngine;
using System.Collections;

public class enemybehaviors : MonoBehaviour {
	//health of enemy
	public int health;
	//is the enemy graced?
	private bool attackable;
	//length of grace period
	public int grace;
	//local call for grace period value
	private int gracee;
	void Start(){
		Debug.Log ("START");
		//default attackable to true
		attackable = true;
		//local call for grace period value
		gracee = grace;
	}
	void Update(){
		Debug.Log ("UPDATE");
		//if enemys health is 0 destroy enemy
		if(health == 0)Destroy (gameObject);
		//if enemy is invincible, decrease grace period remaining
		if(attackable == false){
			gracee=gracee-1;
		}
		//if grace period is 0 allow to be attacked again
		if(gracee == 0){
			attackable = true;
			gracee = grace;
		}
	}
	void OnCollisionEnter (Collision col){
		Debug.Log ("HIT");
		//if sword hits enemy take away health and turn on grace period
		if (col.gameObject.name == "sword" && 	attackable == true) {
			health=health-1;
			attackable = false;
		}
	}

}

I have been trying to make a top down game where you slash a sword at enemies. I tried adding a health and grace period mechanic however but enemies still die in one hit. Any fixes? If its obvious I did something wrong I’m new to Unity.

You are removing health every frame, use OnTriggerEnter instead. But even the trigger might and probably will produce wrong results as you are basically depending on physics collision which are not 100% controllable. Id probably combine event driven logic with custom attacking. And check health for 0 when its actually necessary - not in update. update should only contain actually dynamic logic.

void OnTriggerEnter(Collider other) {
    GameObject hitGo = other.gameObject;

    //your logic
    //if something true
    healthRemove(1);
}

void healthRemove(int amount){
    health -= amount;

    if(health <= 0)Die();
}

void Die(){
    Debug.Log("Died");
}

It looks functional, except I don’t know what value you’ve put in grace and health. Update can be called several hundred times a second, so I don’t recommend reducing an int by 1. This is how time is generally tracked in Unity with Update:

public float grace;
float gracee;

void Start()
{
    gracee = grace;
}

void Update ()
{
    if(attackable == false)
    {
         gracee -= Time.deltaTime;
    }
}

grace is measured in seconds, giving you complete control over how many seconds or milliseconds the grace period will last. Because gracee can move right past zero, the reset can’t assume zero:

if(gracee < 0)
{
     attackable = true;
     gracee = grace;
}

Hope this helps, happy coding :slight_smile: