I have a script for a enemy where it can chase after the player and if close enough, close in and attack the player. If I jump over the enemy and if I time it right, the enemy will “closeIn” and “Attack” but then it will stop pursuing the player and idle instead.
Because I debugged it, I know that it stops pursuing because, while CanMove = false, it goes back to the “MoveMinorEnemy” method (because RelativePositionOfEnemyFromPlayer > MinimumDistanceToCloseIn) and then the code gets stuck in “MoveMinorEnemy” with the CanMove = false.
I cannot explain why it doesn’t go back to CanMove = true. Here’s the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SkeletonWarrior : MonoBehaviour
{
private float speed = 0.5f;
private float MinimumDistanceToInitiateMove = 6f;
private float MinimumDistanceToCloseIn = 3f;
private float MinimumReachDistanceToInitiateAttack = 1f;
private float RelativePositionOfEnemyFromPlayer;
private float AbsolutePositionOfEnemyFromPlayer;
private bool PlayerIsDetected = false;
private Rigidbody2D SkeletonWarriorBody;
private SpriteRenderer SkeletonWarriorRenderer;
private Transform PlayerTransform;
private Animator SkeletonWarriorAnim;
private string WALK_ANIMATION = "Walk";
private string ATTACK_ANIMATION = "Attack1";
private string CLOSE_IN_ANIMATION = "CloseInToAttack";
private bool IsGrounded = true;
//private bool IsAttacking = false;
private string GROUND_TAG = "Ground";
private bool CanMove = true;
// Start is called before the first frame update
private void Awake()
{
SkeletonWarriorBody = GetComponent<Rigidbody2D>();
SkeletonWarriorAnim = GetComponent<Animator>();
SkeletonWarriorRenderer = GetComponent<SpriteRenderer>();
//Player
PlayerTransform = GameObject.Find("Knight").GetComponent<Transform>();
}
void Start()
{
}
// Update is called once per frame
private void Update()
{
RelativePositionOfEnemyFromPlayer = transform.position.x - PlayerTransform.position.x;
AbsolutePositionOfEnemyFromPlayer = Mathf.Abs(RelativePositionOfEnemyFromPlayer);
if (PlayerIsDetected == true)
{
ActIfPlayerIsDetected();
}
else if (AbsolutePositionOfEnemyFromPlayer <= MinimumDistanceToInitiateMove)
{
PlayerIsDetected = true;
ActIfPlayerIsDetected();
}
else
{
}
//Debug.Log(AbsolutePositionOfEnemyFromPlayer);
//Debug.Log(CanMove);
}
private void ActIfPlayerIsDetected()
{
if (AbsolutePositionOfEnemyFromPlayer > MinimumDistanceToCloseIn)
{
//if (CanMove == false)
//{
//}
//else
//{
MoveMinorEnemy();
//}
}
else if ((AbsolutePositionOfEnemyFromPlayer <= MinimumDistanceToCloseIn) && (AbsolutePositionOfEnemyFromPlayer > MinimumReachDistanceToInitiateAttack))
{
CanMove = false;
SkeletonWarriorCloseIn();
}
else
{
CanMove = false;
SkeletonWarriorAttack();
}
}
private void MoveMinorEnemy()
{
if (CanMove == true)
{
if (RelativePositionOfEnemyFromPlayer > 0)
{
SkeletonWarriorAnim.SetBool(WALK_ANIMATION, true);
SkeletonWarriorRenderer.flipX = true;
SkeletonWarriorBody.velocity = new Vector2(-speed, SkeletonWarriorBody.velocity.y);
}
else if (RelativePositionOfEnemyFromPlayer < 0)
{
SkeletonWarriorAnim.SetBool(WALK_ANIMATION, true);
SkeletonWarriorRenderer.flipX = false;
SkeletonWarriorBody.velocity = new Vector2(speed, SkeletonWarriorBody.velocity.y);
}
else
{
}
}
else
{
//SkeletonWarriorAnim.SetBool(WALK_ANIMATION, false);
//
//Debug.Log("This");
//Debug.Log(CanMove);
//Debug.Log(RelativePositionOfEnemyFromPlayer);
//Debug.Log(SkeletonWarriorAnim.GetBool(WALK_ANIMATION));
//Debug.Log(SkeletonWarriorAnim.GetBool(CLOSE_IN_ANIMATION));
//Debug.Log(SkeletonWarriorAnim.GetBool(ATTACK_ANIMATION));
//SkeletonWarriorBody.velocity = new Vector2(0, SkeletonWarriorBody.velocity.y);
}
}
void SkeletonWarriorCloseIn()
{
//SkeletonWarriorAnim.SetBool(WALK_ANIMATION, false);
//SkeletonWarriorAnim.SetBool(ATTACK_ANIMATION, false);
if (/*SkeletonWarriorAnim.GetCurrentAnimatorStateInfo(0).IsName(ATTACK_ANIMATION) ||*/ SkeletonWarriorAnim.GetCurrentAnimatorStateInfo(0).IsName(CLOSE_IN_ANIMATION))
{
}
else
{
if (RelativePositionOfEnemyFromPlayer > 0)
{
SkeletonWarriorAnim.SetBool(CLOSE_IN_ANIMATION, true);
SkeletonWarriorRenderer.flipX = true;
SkeletonWarriorBody.velocity = new Vector2(-6 * speed, SkeletonWarriorBody.velocity.y);
}
else if (RelativePositionOfEnemyFromPlayer < 0)
{
SkeletonWarriorAnim.SetBool(CLOSE_IN_ANIMATION, true);
SkeletonWarriorRenderer.flipX = false;
SkeletonWarriorBody.velocity = new Vector2(6 * speed, SkeletonWarriorBody.velocity.y);
}
else
{
}
}
}
void SkeletonWarriorAttack()
{
//SkeletonWarriorAnim.SetBool(WALK_ANIMATION, false);
//SkeletonWarriorAnim.SetBool(CLOSE_IN_ANIMATION, false);
if (SkeletonWarriorAnim.GetCurrentAnimatorStateInfo(0).IsName(ATTACK_ANIMATION) /*|| SkeletonWarriorAnim.GetCurrentAnimatorStateInfo(0).IsName(CLOSE_IN_ANIMATION)*/)
{
}
else
{
SkeletonWarriorAnim.SetBool(ATTACK_ANIMATION, true);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag(GROUND_TAG))
{
IsGrounded = true;
//CharacterAnim.SetBool(JUMP_ANIMATION, false);
//Debug.Log(collision.gameObject.name);
}
}
void AttackEnded()
{
SkeletonWarriorAnim.SetBool(ATTACK_ANIMATION, false);
CanMove = true;
}
void CloseInEnded()
{
SkeletonWarriorBody.velocity = new Vector2(0, SkeletonWarriorBody.velocity.y);
SkeletonWarriorAnim.SetBool(CLOSE_IN_ANIMATION, false);
SkeletonWarriorAttack();
}
}
I’ve tried debugging almost everywhere, I feel it has to do with the
if (SkeletonWarriorAnim.GetCurrentAnimatorStateInfo(0).IsName(ATTACK_ANIMATION) /*|| SkeletonWarriorAnim.GetCurrentAnimatorStateInfo(0).IsName(CLOSE_IN_ANIMATION)*/)
{
}
portion and that is why it doesn’t start the animation and ultimately doesn’t call the attackEnded anim event where CanMove is turned back to true.
Can someone help me understand how it gets stuck and how to solve my problem? I’ve been trying to find a solution for a long while now and I don’t know how to proceed.
Zirgud is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1