angle based attack animation

here’s the relevant block of code:

float xDiff = enemy1.transform.position.x - transform.position.x;
            float yDiff = enemy1.transform.position.y - transform.position.y;
            float zval = transform.position.z;
            Vector3 attackangle = new Vector3 (xDiff, yDiff, zval);
            // animate
            Debug.Log("AttackEnemy");
            if (Vector3.Angle(attackangle, Vector3.left) >= 0 && Vector3.Angle(attackangle, Vector3.left) <= 45)
            {
                Debug.Log("AttackEnemy");
                animator.Play("HALeft2");
            }
            else if (Vector3.Angle(attackangle, Vector3.right) >= 0 && Vector3.Angle(attackangle, Vector3.right) <= 45)
            {
                animator.Play("HARight2");
            }
            else if (Vector3.Angle(attackangle, Vector3.up) >= 0 && Vector3.Angle(attackangle, Vector3.up) < 45)
            {
                animator.Play("HAUp2");
            }
            else if (Vector3.Angle(attackangle, Vector3.down) >= 0 && Vector3.Angle(attackangle, Vector3.down) < 45)
            {
                animator.Play("HADown2");
            }

sometimes the attack left animation will play but mainly it plays the apparent default animation, which is move left. i had it playing the attack left animation and not the move left animation when the logic was wrong.

any ideas what could be wrong? i’m a mediocre mathematician. i sketched it out in paint and i think i did attackangle correctly.

this script is on the hero object btw, so transform.position refers to the hero’s position.

edit: sometimes i can get the correct animations to play, but it’s very finicky. not sure why.
edit2: maybe the vector i made doesn’t give the angle between hero and enemy? that is one avenue to investigate.

I think the only way you’re going to get to the bottom of this quickly is to start printing out the angles before you compare them, by perhaps assigning them to temporary variables, THEN using those variables to compare and make your decisions.

You can get this info with either Debug.Log or else push it out to a UnityEngine.UI.Text object in your scene to see it in real time.

Also, you really want to call “complex-ish” functions like Vector3.Angle() as few times as possible, so calling it twice to create the same result and compare it against two constants is definitely something to avoid. Call it once for each combination of inputs, save the result (print it out as above), then use it to compare.

1 Like

maybe what i need is a rubber duck, lol. (actually i have one right by my computer.)

i did as Kurt-Dekker suggested, and it was illuminating. i created a canvas with four text boxes, one to display each angle in real time - left, right, up, and down. basically what angle is being shown does not always correlate with which animation is being played, and the angles aren’t all what i predicted. maybe i should show more code? i don’t have much idea yet of how to fix this.

i guess i could use different functions for the angles, so that they ARE what i predicted and wanted, but i don’t know how i would do the math for the angles i need. maybe i’ll use something other than vector3.direction. hmmm…

edit: i’ll post pictures tomorrow, asap. can’t do it today because my parents are asleep …

here’s my images:



edit: okay, i had my text boxes named wrong, so the angles weren’t in the right order in the debug boxes. also, because there isn’t always an angle between 0 and 45, i have to use a different algorithm for animation, but this isn’t a problem. i’ll see if it corrects my issue with mecanim. mecanim has given me problems in the past that i don’t fully understand, though i have functional code for example in my movement function. i’m not sure why it doesn’t work when it doesn’t though.

https://hastebin.com/wavakuqixe.cpp

for my new algorithm, i’m getting an error in the for loop (on the angles statements) that cannot convert float to int. not sure how to get it working.

edit: works if you use var for i! learned that trick from someone in chat.

Generally you want to just cast in this case. For example:

 int i = 0;
 float f = 1.2f;
 i = f;     // error
 i = (int)f;    // casting the float down to an int
1 Like