Untitled
unknown
plain_text
a month ago
5.7 kB
6
Indexable
using UnityEngine;
public class EnemyController : MonoBehaviour
{
public enum EnemyStates { Patrol, Chase, Attack, Hit, Death }
public EnemyStates state = EnemyStates.Patrol;
public Animator anim;
public Rigidbody2D rig;
public Collider2D col;
public float speed = 5;
public LayerMask floorLayers;
private float direction = 1;
private PlayerController player;
public float chaseDistance = 5;
public float attackDistance = 1;
public float attackDuration = 2;
public float hitDuration = 3;
public float deathDuration = 3;
public Transform attackPoint;
public GameObject attackFX, attackHitFX, hitFX, deathFX;
public float hp = 1;
private float maxHp;
private bool locked = false;
private void Start()
{
maxHp = hp;
player = FindFirstObjectByType<PlayerController>();
}
private void Update()
{
if (locked) return;
anim.SetBool("IsWalking", Mathf.Abs(rig.linearVelocity.x) > 0.1f);
if (Physics2D.Raycast(col.bounds.center, Vector2.down, col.bounds.extents.y * 1.1f, floorLayers))
{
anim.SetBool("IsGrounded", true);
}
else
{
anim.SetBool("IsGrounded", true);
}
switch(state)
{
case EnemyStates.Patrol:
PatrolState();
break;
case EnemyStates.Chase:
ChaseState();
break;
case EnemyStates.Attack:
AttackState();
break;
case EnemyStates.Hit:
HitState();
break;
case EnemyStates.Death:
DeathState();
break;
}
}
private void PatrolState()
{
rig.linearVelocity = new Vector2(direction * speed, rig.linearVelocity.y);
Vector2 point = new(
col.bounds.center.x + col.bounds.extents.x * direction,
col.bounds.center.y);
if(!Physics2D.Raycast(point, Vector2.down, col.bounds.extents.y * 1.1f, floorLayers))
{
direction *= -1;
transform.localScale = new Vector2(direction, 1);
}
float distance = Vector2.Distance(transform.position, player.transform.position);
if (distance < chaseDistance)
{
if (distance < attackDistance)
{
EnterAttack();
}
else
{
state = EnemyStates.Chase;
rig.bodyType = RigidbodyType2D.Dynamic;
}
}
}
private void ChaseState()
{
SetDirection();
rig.linearVelocity = new Vector2(direction * speed, rig.linearVelocity.y);
float distance = Vector2.Distance(transform.position, player.transform.position);
if (distance > chaseDistance)
{
state = EnemyStates.Patrol;
rig.bodyType = RigidbodyType2D.Dynamic;
}
else if (distance < attackDistance)
{
EnterAttack();
}
}
private void AttackState()
{
float distance = Vector2.Distance(transform.position, player.transform.position);
if (distance > attackDistance)
{
if (distance > chaseDistance)
{
state = EnemyStates.Patrol;
rig.bodyType = RigidbodyType2D.Dynamic;
}
else
{
state = EnemyStates.Chase;
rig.bodyType = RigidbodyType2D.Dynamic;
}
}
else
{
EnterAttack();
}
}
private void HitState()
{
state = EnemyStates.Patrol;
rig.bodyType = RigidbodyType2D.Dynamic;
}
private void DeathState()
{
}
private void SetDirection()
{
direction = (player.transform.position - transform.position).normalized.x;
if (direction > 0) direction = 1;
else if (direction < 0) direction = -1;
transform.localScale = new Vector2(direction, 1);
}
private void EnterAttack()
{
SetDirection();
state = EnemyStates.Attack;
rig.linearVelocity = Vector2.zero;
rig.bodyType = RigidbodyType2D.Kinematic;
anim.SetTrigger("Attack");
anim.SetBool("IsWalking", false);
if (attackFX) Instantiate(attackFX, attackPoint.position, attackPoint.rotation);
locked = true;
CancelInvoke(nameof(Unlock));
Invoke(nameof(Unlock), attackDuration);
}
private void Unlock() => locked = false;
public void GetHit(float damage, float push, Vector3 pos)
{
hp -= damage;
locked = true;
rig.bodyType = RigidbodyType2D.Kinematic;
CancelInvoke(nameof(Unlock));
if (hitFX) Instantiate(hitFX, transform.position, transform.rotation);
if (hp > 0)
{
state = EnemyStates.Hit;
anim.SetTrigger("Hit");
Invoke(nameof(Unlock), hitDuration);
rig.linearVelocity = (transform.position - pos).normalized * push;
}
else
{
state = EnemyStates.Death;
anim.SetTrigger("Death");
Invoke(nameof(AutoDestroy), deathDuration);
rig.linearVelocity = Vector2.zero;
if (deathFX) Instantiate(deathFX, transform.position, transform.rotation);
}
}
private void AutoDestroy()
{
Destroy(gameObject);
}
}
Editor is loading...
Leave a Comment