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.
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!