using System.Collections; using System.Collections.Generic; using NaughtyAttributes; using UnityEngine; [RequireComponent(typeof(Rigidbody2D))] public class Entity : MonoBehaviour { [SerializeField] [Required] GameFlowManager gameFlowManager = null!; [field: SerializeField] [field: Required] protected EntityStats stats { get; private set; } [field: SerializeField]protected float Health { get; private set; } [SerializeField]private float movementSpeed; [SerializeField]private float rotSpeed; [SerializeField]private float fov; [SerializeField]private float attackRange; [SerializeField]private float attackDmg; [SerializeField]protected float attackCooldown; protected float attackTimer; [SerializeField]private Transform target; private new string name; private Collider atkCollider; private Vector3 direction; Rigidbody2D rb; bool beingPushed; void Awake() => rb = GetComponent(); protected virtual void Start() { direction = new Vector3(1,0,0); attackTimer = attackCooldown; } protected virtual void FixedUpdate() { //TODO sqrMagnitude? if (beingPushed && rb.velocity.magnitude < stats.MinVelocityWhenPushed) { rb.velocity = Vector2.zero; beingPushed = false; } } protected virtual void Attack(){ // jason: TODO Either have target be Entity instead of transform, or skip Attack when GetComponent() is null Entity targetEntity = target.GetComponent(); bool isTargetAlive = targetEntity.TakeDamage(attackDmg); } protected virtual void SpecialAttack(){ } protected virtual void MoveToTarget(){ direction = Vector3.RotateTowards(direction, (target.position - transform.position), rotSpeed*Time.fixedDeltaTime, 0.0f); if(!IsInAttackRange()){ rb.MovePosition(transform.position + direction * movementSpeed * Time.fixedDeltaTime); } } public void SetTarget(Transform newTarget){ target = newTarget; } public Transform GetTarget(){ return target; } //Apply damage to the entity, returns true if it is still alive public virtual bool TakeDamage(float amount){ Health -= amount; if(Health <= 0){ return false; } return true; } public void SetName(string name){ this.name = name; } protected string GetName(){ return this.name; } protected bool IsInAttackRange(){ return Vector2.Distance(transform.position, target.position) <= attackRange; } protected bool IsLookingAtTarget(){ float angle = Vector2.SignedAngle(direction, (target.position - transform.position)); return angle >= -fov && angle <= fov; } protected void AddImpulse(Vector3 impulse) { beingPushed = true; rb.AddForce(impulse, ForceMode2D.Impulse); } }