using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pathfinding;
using System;
public class BasicEnemy : MonoBehaviour
{
//Refs
[SerializeField] Collider2D _collider2D;
[Header("Pathfinding")]
public Transform target;
public float activateDistance = 1;
[Range(.75f, 2f)] public float pathUpdateInSeconds = 1f;
[Header("Physics")]
public float speed = 200f;
public float nextWayPointDistance = 1f;
public float jumpNodeHeightRequirement = 0.8f;
public float jumpModifier = .3f;
public float jumpCheckOffset = .1f;
//ToDo: Make all of the following Customizables a Scriptable Object
[Header("Customizable")]
public bool jumpEnabled = true;
public bool followEnabled = true;
public bool directionLookEnabled = true;
private Path path;
private int currentWayPoint = 0;
private bool isGrounded = false;
bool isTargetInDistanceFlag = false;
private float pathUpdateTimer = 1f;
[SerializeField, HideInInspector()] private Seeker seeker;
[SerializeField, HideInInspector()] private Rigidbody2D _rb;
private void Start() { pathUpdateTimer = pathUpdateInSeconds; }
private void Update()
{
isTargetInDistanceFlag = false;
if (PauseManager.paused) { return; }
isTargetInDistanceFlag = TargetInDistance() && followEnabled;
if (pathUpdateTimer > 0) { pathUpdateTimer -= Time.deltaTime; }
else
{
UpdatePath();
pathUpdateTimer = pathUpdateInSeconds;
}
}
private void FixedUpdate()
{
if (PauseManager.paused) { return; }
if (isTargetInDistanceFlag) PathFollow();
}
private void PathFollow()
{
if (path == null) { return; }
//Reached end of Path?
if (currentWayPoint >= path.vectorPath.Count) { return; }
// See if colliding with anything
Vector3 startOffset
= transform
.position - new Vector3
(0f, _collider2D
.bounds.extents.y + jumpCheckOffset
);
isGrounded = Physics2D.Raycast(startOffset, -Vector3.up, 0.05f);
// Direction Calculation
Vector2 direction = ((Vector2)path.vectorPath[currentWayPoint] - _rb.position).normalized;
Vector2 force = direction * speed * Time.fixedDeltaTime;
if (jumpEnabled && isGrounded)
{
if (direction.y > jumpNodeHeightRequirement)
{
_rb.AddForce(Vector2.up * jumpModifier * speed * 2);
}
}
// Movement Horizontal
_rb.AddForce(force * _rb.mass);
// Next Waypoint
float distance = Vector2.Distance(_rb.position, path.vectorPath[currentWayPoint]);
if (distance < nextWayPointDistance) { currentWayPoint++; }
// Direction Graphics Handling
if (directionLookEnabled)
{
if (_rb.velocity.x < 0.05f)
{
transform
.localScale = new Vector3
(-1f
* Mathf
.Abs(transform
.localScale.x), transform
.localScale.y, transform
.localScale.z);
}
else if (_rb.velocity.x > -0.05f)
{
transform
.localScale = new Vector3
(Mathf
.Abs(transform
.localScale.x), transform
.localScale.y, transform
.localScale.z);
}
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Player"))
{
var necromancer = collision.gameObject.GetComponent<PlayerNecromancerController>();
if (necromancer.alive) { GameManager.Instance.ResetScene(); }
}
}
private bool TargetInDistance() { return Vector2.Distance(transform.position, target.transform.position) < activateDistance; }
private void UpdatePath()
{
if (TargetInDistance() && followEnabled && seeker.IsDone())
{
seeker.StartPath(_rb.position, target.position, OnPathComplete);
}
}
private void OnPathComplete(Path p)
{
if (!p.error)
{
path = p;
currentWayPoint = 0;
}
}
private void OnValidate()
{
if (_rb == null) { _rb = GetComponent<Rigidbody2D>(); }
if (seeker == null) { seeker = GetComponent<Seeker>(); }
if (_collider2D == null) { _collider2D = GetComponent<Collider2D>(); }
}
}