- Home /
Having problem with sword attacking enemy every frame and instantly killing him
Basically I have an attack script for my player to attack a goblin with a sword, but every time he hits him, It instantly kills the enemy.
I tried making a bool that would only allow damage to be taken 1 time, but nothing happened. anyone have any ideas what happened?
Here's my script (This was put on the player) :
public int playerHealth = 15;
public int playerDamage = 2;
bool AttackTimer = true;
void OnCollisionEnter(Collision col)
{
if (col.transform.tag == "EnemySword" && AttackTimer == true)
{
playerHealth -= 2;
AttackTimer = false;
Debug.Log(AttackTimer);
if (playerHealth <= 0)
{
Destroy(gameObject);
}
}
}
void OnCollisionExit(Collision col)
{
AttackTimer = true;
}
void Start () {
}
// Update is called once per frame
void Update () {
}
}
If the players is killed instantly, this must mean that the OnCollisionEnter() is called multiple times, because this is the only place where the health is reduced. Try removing the OnCollisionExit() function and see if it still happens. It could be something in the range of: The player gets hit with a collider, the two colliders bounce a bit. This causes the collider to exit again, turning the variable AttackTimer true again. If the collider is still in motion, it will hit again and reduce the health once more. This process will repeat until the player object is destroyed).
So try to remove line 21: AttackTimer = true; The variable should never turn to true that way. If it is still happening, there something else going on.
@metalted Thanks for responding, but it seems that when I remove OnCollisionExit, the enemies now won't take damage at all. I think that the collides could be bouncing off each other, but this doesn't seem to be the way to solve it. Could it have to do with the collier on my sword? I'm using a mesh collider.
In your OnCollisionEnter add this line before the if loop:
Debug.log ("Hit by: "+col.transform.name+". Tag:"+col.transform.tag);
This will confirm the name of the object and tag that is colliding with the player, whilst also confir$$anonymous$$g that the collision has actually been detected.
Sometimes you'll have unexpected results here (like the collision is actually an arm or hand).
If the tag matches "EnemySword" you know there's either a problem with the bool state stopping it from starting the IF loop.
If you're still struggling, post the console log so we can see what it's doing.
I'd also add the following as the first line in your inner loops:
Debug.log ("Starting attack loop");
Debug.log ("Triggered collisionExit loop");
These will help you debug if the routines are being triggered as expected.
@$$anonymous$$evRev @metalted talted Hey thanks, but I've tried that and I now seem to get an error "unityengine.Debug does not contain a definition for log"
Also I've updated the PlayerHealth script a bit it now looks like this:
using System.Collections; using UnityEngine.Experimental.UIElements; using System.Collections.Generic; using UnityEngine;
public class PlayerHealth : $$anonymous$$onoBehaviour {
public int playerHealth = 15;
public int playerDamage = 2;
public float flashSpeed = 5f;
public Image damageImage;
public Enemy$$anonymous$$ovement enemy;
bool didSwing = false;
void OnCollisionEnter(Collision col)
{
Debug.log ("Hit by: " + col.transform.name + ". Tag:" + col.transform.tag);
if (col.transform.tag == "EnemySword" && didSwing == true)
{
enemy.enemyHealth -= 2;
if (enemy.enemyHealth <= 0)
{
Destroy(gameObject);
}
didSwing = false;
}
}
}
$$anonymous$$y swing script (allows the player to swing) looks like this:
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class swing : $$anonymous$$onoBehaviour { Animator anim; bool didSwing = false; public Enemy$$anonymous$$ovement enemy;
void Start()
{
//get the animator
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
//call triggers via keypress - you can also assign them via the preset inputs
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.$$anonymous$$ouse0))
{
anim.SetTrigger("swingA");
didSwing = true;
Debug.Log("swapTrue");
}
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.$$anonymous$$ouse1))
{
anim.SetTrigger("swingB");
didSwing = true;
Debug.Log("swapTrue");
}
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.W))
anim.SetTrigger("Run");
if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.Space))
anim.SetTrigger("Jump");
}
void OnCollisionEnter(Collision col)
{
if (col.transform.tag == "EnemySword" && didSwing == true)
{
enemy.enemyHealth -= 2;
if (enemy.enemyHealth <= 0)
{
Destroy(gameObject);
}
didSwing = false;
}
}
}
Thanks for the help though guys
$$anonymous$$ake sure you have the right case for the word Log after Debug.
The additional debug lines will confirm what's happening when. You really need to see those to be able to continue troubleshooting.
Fix the debug lines and let us know the results.