Day 118 — Setting up Enemy Combat State
Hey and welcome!
In this one I’m going to show you how to get the enemy into a combat state when they’ve been hit and exit it when the player moves a certain distance away.
First things first, find the Attack sprites for your enemy and create a new animation for them called Attack. Go into your animator and create an InCombat parameter and add this as a true condition heading from Idle to Attack and a false condition from Idle to Walk. Add another condition this time heading from Attack to Idle and make sure that all three of these conditions have an exit time.
Your animator should look something like the above. Before we get to the code, go ahead and create an image object that’s set as a child to your Sprite object that’s in your enemy object similar to what we did for the Player. In the Sprite Renderer set the order in layer to match your player and change the sprite to a UISprite.
Now add a Box Collider 2D and Rigidbody 2D component making sure that the collider’s active status is unchecked and that it’s a trigger. Then make sure that the rigidbody’s gravity scale is set to 0. Create 2 new layers called Enemy and EnemyAttack and assign them to your sprite and hit_box accordingly. Remember to head into your project settings and stop these layers from colliding with each other in the Layer Collision Matrix.
Head over to your Attack animation in the animation window and hit the record button. On the first frame re-enable your box collider and map it out over the enemy’s weapon and then do the same for every frame as you did for the player’s hit box.
In your Enemy class add in this new bit of code:
protected bool isHit = false;public virtual void Movement()
{
if (currentTarget == pointA.position)
{
sprite.flipX = true;
}
else
{
sprite.flipX = false;
} if (transform.position == pointA.position)
{
currentTarget = pointB.position;
anim.SetTrigger("Idle");
}
else if (transform.position == pointB.position)
{
currentTarget = pointA.position;
anim.SetTrigger("Idle");
} if (isHit == false)
{
transform.position = Vector3.MoveTowards(transform.position, currentTarget, speed * Time.deltaTime);
} float distance = Vector3.Distance(player.transform.localPosition, transform.localPosition); if (distance > 4.0f)
{
isHit = false;
anim.SetBool("InCombat", false);
}
}
This calculates the distance between the player and the enemy and will change the combat state when the player moves beyond 4.0f. Now open up your Skeleton script and add this in:
public override void Movement()
{
base.Movement();
Vector3 direction = player.transform.localPosition - transform.localPosition; if (direction.x > 0 && anim.GetBool("InCombat") == true)
{
sprite.flipX = false;
}
else if (direction.x < 0 && anim.GetBool("InCombat") == true)
{
sprite.flipX = true;
}
}public void Damage()
{
Debug.Log("Damage!");
Health--;
anim.SetTrigger("Hit");
isHit = true;
anim.SetBool("InCombat", true); if (Health < 1)
{
Destroy(this.gameObject);
}
}
This bit of code we’ve added works out the direction to face depending where the player is and sets the InCombat bool in our animator to true which will cause the enemy to pause and continually take swings at the Player until their InCombat is set to false.
That’s not looking too bad their, our enemies are starting to get more intelligent!