- Home /
How register damage only once per collision?
Straight to the point - i have character with no colliders on him, but my Character Controller acts like one for some reason. When enemy swings his weapon. the collider on weapon enables to deal damage for like 0,1 sec through coroutine and then disabling. I used OnCollisionEnter and OnTriggerEnter in weapon script, so it suppose to register collision only once. But somehow it deals damage multiple times almost randomly. And i can't understand why. When weapon collides, script automatically disables it's own collider and stops coroutine. Pls help, it's very confusing сonsidering my character even don't have any colliders :/ There's my script on weapon:
public void Attack()
{
StartCoroutine(EnableHitbox());
}
IEnumerator EnableHitbox()
{
yield return new WaitForSeconds(openFrame);
GetComponent<BoxCollider>().enabled = true;
yield return new WaitForSeconds(closeFrame);
GetComponent<BoxCollider>().enabled = false;
}
void OnTriggerEnter(Collider other)
{
if (transform.root.tag == "Enemy")
{
int healthDamage = 0;
if (other.transform.tag == "Player")
{
Debug.Log(other.name);
//GetComponent<BoxCollider>().enabled = false;
StopCoroutine(EnableHitbox());
other.transform.root.GetComponent<PlayerStats>().Health(healthDamage = slash);
}
}
}
Answer by TheSpherinder · Jun 06 at 05:59 AM
First of all, I would recommend giving the player a collider to avoid any issues later, for a lot of things, you need a collider on both objects for the collider to recognise an overlap, otherwise, because there is no second collider for the first collider to collide with, it might as well not be touching anything.
As for the weapon, if it disables it's collider at the end of the script, then it will not be enabled to detect a collision the next time the script runs.
I would suggest changing your code to be something like (this is not actual code):
private float myTimer;
myTimer = 10;
Fixed Update()
{
if (Weapon is colliding with the players collider, once the player has one)
{
if (myTimer > 10)
{
deal damage to the player;
myTimer = 0;
}
myTimer = myTimer + 1
//I know there is a quicker way to do that, but I think like that, so X = X+ 1 it is
//so myTimer, is a cooldown, and every time the timer is larger than ten, it sets to 0, and does damage, if it is touching the player
}
And if the player not having a collider is necessary, just remember you can disable collisions with layers for the player in the layer collision matrix.
When i add a coliider to player actually nothing changes, and it's main issue with this bc i can't afford disabling CC - debug prints that there was many collisions despite that was one hit and weapon's collider disables instantly.
iStrange, bc when enemy weapon collides with character with no colliders, in debug prins out that there's collision with something with tag "player", so i assume it counts it like a legit collision.t might as well not be touching anything.
ANo, the "Attack" function called from another script, driving enemy's AI, so collider enables every time player enter attack range and it has cooldown. I see what Your code doing, but it's the same as disabling collider after entering first collision. I tried the same with booleans and have same results. Disabling collider with OnCollisionExit also didn't work for me. Sorry for bad english.s for the weapon, if it disables it's collider at the end of the script, then it will not be enabled to detect a collision the next time the script runs.
Answer by DedWnutry · 6 days ago
I'm alredy figure it out. The issue was within another script - Attack function was activating when enemy's AI selecting the animation attack type randomly. It generates random numbers many times within one frame. Therefore attack function was called multiple times and coroutine enables collider continuosly. So it was nothing with OP script, simply my fault. The solution to this just make exit time for attack animations.