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(); 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(); } if (seeker == null) { seeker = GetComponent(); } if (_collider2D == null) { _collider2D = GetComponent(); } } }