Enemy AI movement Problems
Firstly this is my first post so I apologise if some things don't work/aren't clear. I have been working through a course to make a 2d platformer in unity. One of the scripts doesn't work as it should and I have checked it multiple times against theirs. I have also made some modifications to it to try to get it to work.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySkeleton : MonoBehaviour
{
private Rigidbody2D MyBody;
[Header("Movement")]
public float moveSpeed;
private float minX, maxX;
public float distance;
public int dir;
private bool detect;
private Transform playerPos;
private Animator anim;
// Start is called before the first frame update
[Header("Attack")]
public Transform attackPos;
public float attackRange, attackDir;
public LayerMask PlayerLayer;
public int damage;
public AudioClip axeSwing;
void Start()
{
anim = GetComponent<Animator>();
playerPos = GameObject.Find("Assassin").transform;
MyBody = GetComponent<Rigidbody2D>();
maxX = transform.position.x + (distance / 2);
minX = maxX - distance;
}
// Update is called once per frame
void Update()
{
if (Vector3.Distance(transform.position, playerPos.position) <= 1.5f)
{
DetectandAttack();
}
else
{
Patrol();
}
Death();
if (MyBody.velocity.x > 0)
{
transform.localScale = new Vector2(1.3f, transform.localScale.y);
anim.SetBool("Attack", false);
}
else if (MyBody.velocity.x < 0)
{
transform.localScale = new Vector2(-1.3f, transform.localScale.y);
}
}
void DetectandAttack()
{
if (Vector2.Distance(playerPos.position, transform.position) >= 0.25f)
{
Vector3 PlayerDir = (playerPos.position - transform.position).normalized;
if (!detect)
{
attackDir = 1f * PlayerDir.x;
transform.localScale = new Vector2(1.3f * attackDir, transform.localScale.y);
detect = true;
anim.SetTrigger("Detect");
}
if (anim.GetCurrentAnimatorStateInfo(0).IsName("SkeletonDetect"))
{
return;
}
if (PlayerDir.x > 0)
{
MyBody.velocity = new Vector2(moveSpeed + 0.4f, MyBody.velocity.y);
}
else
{
MyBody.velocity = new Vector2(-(moveSpeed + 0.4f), MyBody.velocity.y);
}
}
else if (Vector2.Distance(playerPos.position, transform.position) <= 0.25f)
{
MyBody.velocity = new Vector2(0, MyBody.velocity.y);
anim.SetBool("Attack", true);
}
}
void Patrol()
{
detect = false;
switch (dir)
{
case -1:
if (transform.position.x > minX)
{
MyBody.velocity = new Vector2(-moveSpeed, MyBody.velocity.y);
}
else
{
dir = 1;
}
break;
case 1:
if (transform.position.x < maxX)
{
MyBody.velocity = new Vector2(moveSpeed, MyBody.velocity.y);
}
else
{
dir = -1;
}
break;
}
}
void Death()
{
if (anim.GetBool("Death"))
{
MyBody.velocity = Vector2.zero;
GetComponent<Collider2D>().enabled = false;
MyBody.isKinematic = true;
anim.SetBool("Attack", false);
return;
}
}
public void Attack()
{
SoundManager.instance.PlaySoundFx(axeSwing, .2f);
Collider2D attackPlayer = Physics2D.OverlapCircle(attackPos.position, attackRange, PlayerLayer);
if (attackPlayer != null)
{
if (attackPlayer.tag == "Player")
{
attackPlayer.gameObject.GetComponent<PlayerHealth>().TakeDamage(damage);
}
}
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(attackPos.position, attackRange);
}
void Flip()
{
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
Not sure if anyone can make any sense of it. Basically I want the enemy to:
Patrol a certain distance(currently works).
detect player, play detect animation whilst remaining stationary(sort of works).
run towards player and attack
remain stationary while attacking and remain in the original orientation without flipping mid attack.
This is my attempt at uploading a video of what is currently happening. [1]: /storage/temp/152805-firstplatformer-testscene-pc-mac-linux-standalone.zip
I think there is a problem with how the local scale is set as it depends on velocity, and when the enemy attacks its velocity is set to zero. I would really appreciate anyone's help on this, its almost certainly a small fix or me being silly! Sorry its such a mess!
Answer by tormentoarmagedoom · Feb 14, 2020 at 01:40 AM
Hello there.
You need to give specifyc info, we can not test your code, just read it.
Why does ont work? Do you have any error? At wich point result is not the expected? Did you debugged the code while running? Look on how to debug the code, so you can see all variable values each moment, and detect where exactly the code dont do what you expected.
With all this info, repost again posting only the exact question on how to use a function.
Also recommend 100% spend some hours learning, reding, and trying to use UNITY NAV MESH SYSTEM to move your characters. UNITY ANIMATIONS to animate your characters. UNITY TRIGGER COLLIDERS to make objects detect other objects.
Do try to go fast.
Good luck!
Thanks for the reply! The game runs with this code and you can see how It runs in the video if it works for you. unfortunately it doesn't work as intended and I cant work out why. The functions that I think are causing it ate the DetectandAttack() function and the section in the update method which sets the local scale of the enemy. I would repost but I think you need the whole context to actually be able to help ?
Your answer
Follow this Question
Related Questions
How do i make a simple 2D AI enemy? 0 Answers
Enemy AI. How to make the AI chase the player by using the exact same moves as the player. (2D) 1 Answer
How I make an npc move when I get near it? 0 Answers
Enemy AI ignores the distance from the player 0 Answers
How to have multiple enemies (currently having to kill them in order) 1 Answer