1
\$\begingroup\$

I'm currently trying to add a melee-slash attack to my Sidescroller.

For that I decided to to have an invisible box-colliders infront of my character. My idea is to activate it when the attack-key is pressed and leave it active for the duration of the attack before turning it inactive again.

I know from a previous attempt with a dash instead (didn't work out on the movement for it) that my code for the attack-triggering in the player-script works just fine, so now in my box-collider infront of the player I have:

    public GameObject Player;
//public GameObject Box;
bool attack = false;
//Collider c;

void Awake () 
{
    Player = GameObject.FindGameObjectWithTag ("Player");
    //Box = GameObject.FindGameObjectWithTag ("AttackBox");
    gameObject.collider.enabled = false;
}

void Update () 
{
    Player pstats = Player.GetComponent<Player>();
    attack = pstats.attacking;

    if (!attack) 
    {
        gameObject.collider.enabled = false;
    }

    if (attack) 
    {
        gameObject.collider.enabled = true;
    }

}

And in my Enemy script I have

    void OnTriggerEnter(Collider collision) 
{
    Player pstats = Player.GetComponent<Player>();
    if (collision.gameObject.tag == "Player") {
        collision.gameObject.GetComponent<Player>().PlayerHit();
    }

    if (collision.gameObject.tag == "AttackBox") 
    {
        pstats.CurrentEXP += 25;
        EnemyDeath ();
    }

}

Though the hit isn't recognized.

The issue I see is that probably the OnTriggerEnter is the issue since the Enemy tends to be allready inside the attack-box collider when the attack is triggered. I tested a bit with the Debug-Log and the box is activated at least, so it should really be just the issue of calling the Trigger at the right time.

Are there any alternatives to OnTriggerEnter that would be working better?

edit: I tried adding this right below my collision-part in the enemy-script:

    void OnTriggerStay(Collider collision) 
{

    Player pstats = Player.GetComponent<Player> ();
    if (collision.gameObject.tag == "AttackBox") 
    {
        pstats.CurrentEXP += 25;
        EnemyDeath ();
    }

}

void OnTriggerExit(Collider collision)
{
    Player pstats = Player.GetComponent<Player> ();
    if (collision.gameObject.tag == "AttackBox") 
    {
        pstats.CurrentEXP += 25;
        EnemyDeath ();
    }
}

Though the hit is still not recognized.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

For a situation like this you'd be better off using something like a OverlapSphere. Or if you're using 2D, you have a few more options with the OverlapAreaAll or the OverlapCircleAll methods.

All of these methods are going to return a list of colliders that intersect with the shape you choose (sphere, circle, rectangle). These have the additional benefit of being able to specify a layer mask to ensure you're only colliding the the objects in your scene you want to collided with, in this case, enemy hit boxes.

Once you have a list of colliders that intersect with your shape, you can iterate through them and do more complex collision checking, or just go straight to applying damage.

For example, your attack might look like this:

void Attack() {
    Player pstats = Player.GetComponent<Player> ();
    Collider[] hitColliders = Physics.OverlapSphere(Player.transform.position, pstats.attackRadius, Enemy.LayerMask);
    int i = 0;
    while (i < hitColliders.Length) {
        pstats.CurrentEXP += 25;
        EnemyDeath ();
    }
}

Where you'll need to define an attackRadius and the Enemy.LayerMask. If you're not sure how to use layer masks you can learn more about them in this video I made.

\$\endgroup\$
3
  • \$\begingroup\$ Well, in my current case, I have a 2.5D Platformer. Both the Enemy-hitbox and my Attack-hitbox are just that, boxes/cubes. Though I'll try out that LayerMask option and see if it works out. \$\endgroup\$
    – m41n
    Jun 26, 2014 at 8:46
  • \$\begingroup\$ Watched your video now, though I still have trouble finding out how exactly to work with the LayerMasks. I know what they do now, but not really sure how to implement them into my problem. my current attack-method in the player script looks basicly like this: (moved to additional comment due to length) \$\endgroup\$
    – m41n
    Jun 26, 2014 at 9:13
  • \$\begingroup\$ public void SlashRight() { audio.Play (); attacking = true; SlashUsingRight = true; controller.enabled = false; StartCoroutine (WaitForSlashToEnd ()); } (sorry for bad formatting, no idea how to do that in comments) \$\endgroup\$
    – m41n
    Jun 26, 2014 at 9:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .