Attack timer using Time.deltaTime won't reach 0

I am new to programming, started 3 days ago. Starting to get a good feel for it also, experimenting with raycasting and melee combat atm. After making a short separate script attached to the melee weapon so that I can call the damage function using animation events (ps: it failed, but that’s not the issue here), I just deleted the script and started the game again to check if anything else broke.

Sure enough, now my attackTimer won’t ever reach zero.
It is capable of being set to 0, it will also decrease. But if I set the attackTimer to 3, it will only decrease to 1.5, and if I set the attackTimer to 1.5, it goes to 0.000089.

I haven’t really changed anything, and I double-checked several times, and also restarted Unity.

Could anyone take a quick look at this code and see if they can tell why my attackTimer won’t reach 0 exactly anymore?

using UnityEngine;
using System.Collections;

public class MeleeAttack : MonoBehaviour {

	float damage = 20;
	float stabMod = 1.5f;
	float swingMod = 1;
	float mod;
	float Distance;
	float MaxDistance = 3;
	float attacking;
	int done_attacking = 1;
	string mation;
	private float attackTimer = 0f;
	public float coolDown = 3f;
	private GameObject myWeapon;
	private GameObject player;
//	public Transform targethit;
//	public float damagedone;
//	public int somethingishit = 1;

	void Awake()
	{
		myWeapon = GameObject.FindGameObjectWithTag("myWeapon");
		myWeapon.animation["Stab"].speed = coolDown;
		myWeapon.animation["Swing"].speed = coolDown;
		player = GameObject.FindGameObjectWithTag("MainCamera");
	}
	
	void  Update ()
	{
		#region Currently attacking? timer
		if (attacking > 0)
			attacking -= Time.deltaTime;

		if (attacking < 0)
			attacking = 0;

		if (attacking == 0)
				done_attacking = 1;

		if (done_attacking == 0)
		//  forward = player.transform.TransformDirection(Vector3.forward) * 10;
		//	Debug.DrawRay(player.transform.position, forward, Color.green);

		#endregion
		#region Attack timer
		if (attackTimer > 0)
		{
			attackTimer -= Time.deltaTime;
			Debug.Log (attackTimer);
		}

		if (attackTimer < 0)
			attackTimer = 0;

		if (attackTimer == 0)
			Debug.Log ("Ready!");

		if (done_attacking == 1)
			myWeapon.animation.Play ("Idle");
		#endregion
		#region attack input
		if (Input.GetKeyUp (KeyCode.Mouse0) && attackTimer == 0 && done_attacking == 1)
			{
				mod = swingMod;
				Attack(mod);
			}

		if (Input.GetKeyUp (KeyCode.Mouse1) && attackTimer == 0 && done_attacking == 1)
			{
				mod = stabMod;
				Attack(mod);
			}
		#endregion
	}
	void Attack(float mod)
	{
		//modifiers
		if (mod == swingMod)
			mation = "Swing";
		if (mod == stabMod)
			mation = "Stab";

		//timers
		attackTimer = coolDown;
		done_attacking = 0;
		attacking = myWeapon.animation[mation].length;

		//animation
		myWeapon.animation.Play(mation);


		//hit detection
		RaycastHit hit;
		//Debug.DrawRay(player.transform.position, player.transform.forward, Color.green);
		if(Physics.Raycast (player.transform.position, player.transform.forward, out hit))
		{
			Distance = hit.distance;
			if (Distance < MaxDistance)
				//targethit = hit.transform;
				//somethingishit = 1;
				//damagedone = damage * mod;
				hit.transform.SendMessage("ApplyDamage", (damage * mod), SendMessageOptions.DontRequireReceiver); 

		}

	}
}

First let me start off by saying welcome to the world of programming! :slight_smile:

One thing I noticed is that you are not using a bool, is there a reason for that?

You can change the ‘done_attacking’ to be a bool type (true/false) that will make it a bit easier to read.

Also, next time you post, please only post the relevant code parts.

We don’t need the parts of the code that are not related to the issue (like the ray casting for example) and it makes it harder to truck down the issue.

Now for your issue, ‘Time.deltaTime’ is the time passed between two frames.

So the chance of it being a full number that can actually be 0 is really low.

So always check for below 0.

Join your checks like so:

if (attacking <= 0)
{
    attacking = 0;
    done_attacking = 1;
}

Hope this helps :slight_smile:

I’d think that instead of using:

if (attackTimer > 0)
        {
            attackTimer -= Time.deltaTime;
            Debug.Log (attackTimer);
        }

You should use:

if (attackTimer > 0)
        {
            attackTimer -= 1 * Time.deltaTime;
            Debug.Log (attackTimer);
        }

IIRC, Time.deltaTime by itself won’t really do much of anything.