Problem with top down combat

Hey community! I’m working on a 2D Zelda-like. I want to be able to swap weapons / attacks on enemies. What I’ve done is animate the enemy to have an attack on all cardinal directions ( up, right, down, left ). I then have my attack as a child. The attack is inactive until the parent enemy animation enables it. At the end of the animation, the attack is set to inactive again. I also rotate the attack to the correct direction, in each enemy animation. This works MOSTLY fine. Sometimes however, the attack will show at a strange angle, ie not strictly up, right, down, or left. Has anyone run into this? Any advice? These are melee attacks, not projectiles.
Thank you in advance!

Just an unlikely guess, but if you have any colliders here not set to trigger, you may be getting some physics movement of the attack position. Don’t think that is likely your issue though.

May be best to post up the code for how your attack is oriented. May be something weird in there.

Thanks for the reply Derekloffin!

I’ve been doing some debugging. I have a moveX and moveY float to set my animation in the blend tree. I Logged these to console and noticed that the problem occurs when one of those values is around 0.7 or -0.7. I think I need to round to the nearest whole number. I’ll keep the thread posted if I figure it out.

So right after I initiate an attack, I use Mathf.Round() to round both my moveX and moveY. This seems to have fixed the issue. I think my problem now is that I don’t understand blend trees well enough to know why this behavior happened to begin with. As suggested, here’s the script that initiates the attack:

using System.Collections;
using UnityEngine;

public class EnemyAttackInRange : MonoBehaviour
{

[SerializeField]
private Transform target;

[SerializeField]
private float range = 2;

[SerializeField]
private float coolDown = 0.4f;

private ActorStateMachine parentState;
private Animator parentAnimator;
private bool locked = false;

// Start is called before the first frame update
void Start()
{
parentState = GetComponent();
parentAnimator = GetComponent();
}

// Update is called once per frame
void Update()
{
float distance = Vector2.Distance( transform.position, target.position );

if( parentState.GetState() != ActorState.ATTACKING &&
parentState.GetState() != ActorState.HURTING &&
!locked &&
distance <= range )
{
parentState.SetState( ActorState.ATTACKING );
parentAnimator.SetBool( “walking”, false );
StartCoroutine( AttackCo() );
return;
}
}

private IEnumerator AttackCo()
{
locked = true;

float roundX = Mathf.Round( parentAnimator.GetFloat( “moveX” ) );
float roundY = Mathf.Round( parentAnimator.GetFloat( “moveY” ) );

parentAnimator.SetFloat( “moveX”, roundX );
parentAnimator.SetFloat( “moveY”, roundY );
parentAnimator.SetBool( “attacking”, true );

Debug.Log( parentAnimator.GetFloat( “moveX” ) + " " + parentAnimator.GetFloat( “moveY” ) );

yield return null;

parentAnimator.SetBool( “attacking”, false );

yield return new WaitForSeconds( 0.4f );

parentState.SetState( ActorState.IDLING );

yield return new WaitForSeconds( coolDown );

locked = false;
}

}