Skip to content
Snippets Groups Projects
AntiPlayer.cs 4.03 KiB
Newer Older
  • Learn to ignore specific revisions
  • using System.Collections.Generic;
    using UnityEngine;
    
    
    Adrian Paschkowski's avatar
    Adrian Paschkowski committed
    // The main opponent of yours. Defeat him and you win.
    
    public class AntiPlayer : Fighter, IFighterCallback
    
        [SerializeField, Tooltip("How close the AntiPlayer has to be to start attacking, or how far away it has to be to start running towards the target")]
        float maxDistanceToEnemy = 1f;
        [SerializeField] float movementSpeed = 4f;
    
        [SerializeField, Tooltip("After killing an Enemy, how long to stay idle before targeting the next enemy")]
        float delayUntilNextTarget = 0.3f;
    
        string[] attackAnimationTriggers = new string[] { "Attack1", "Attack2", "Attack3" };
    
        List<Fighter> enemies = new List<Fighter>();
        Fighter currentTargetEnemy;
    
        protected override void Awake()
        {
            base.Awake();
    
            fighterType = FighterTypes.ANTI_PLAYER;
            opponentTag = "Enemy";
    
            animator.SetBool("Grounded", true);
        }
    
        protected override void Update()
        {
            base.Update();
    
            if (!alive || currentTargetEnemy == null)
    
    
            var vectorToNextEnemy = currentTargetEnemy.transform.position - transform.position;
    
            var scale = transform.localScale;
    
    Adrian Paschkowski's avatar
    Adrian Paschkowski committed
            // Always face the target Enemy. Flip the scale to also flip the position of the attack hitbox.
    
            scale.x = vectorToNextEnemy.x < 0 ? -initalScale.x : initalScale.x;
            transform.localScale = scale;
    
            // Run towards target enemy if too far away
    
            if (Mathf.Abs(vectorToNextEnemy.x) > maxDistanceToEnemy)
            {
    
    Adrian Paschkowski's avatar
    Adrian Paschkowski committed
                animator.SetInteger("AnimState", 1); // Run Animation
    
                rigidbody.velocity = new Vector2(Mathf.Sign(vectorToNextEnemy.x) * movementSpeed, rigidbody.velocity.y);
    
    Adrian Paschkowski's avatar
    Adrian Paschkowski committed
            }
            else
    
    Adrian Paschkowski's avatar
    Adrian Paschkowski committed
                // No horizontal movement
    
                animator.SetInteger("AnimState", 0);
                rigidbody.velocity = new Vector2(0, rigidbody.velocity.y);
            }
        }
        protected override bool CanAttack()
        {
    
            if (currentTargetEnemy == null)
            {
                return false;
            }
    
    Adrian Paschkowski's avatar
    Adrian Paschkowski committed
            // Can only attack when close enough to the target Enemy
    
            var vectorToNextEnemy = currentTargetEnemy.transform.position - transform.position;
            return Mathf.Abs(vectorToNextEnemy.x) <= maxDistanceToEnemy;
        }
    
    
        protected override void Attack()
        {
    
            animator.SetTrigger(attackAnimationTriggers[Random.Range(0, attackAnimationTriggers.Length)]);
    
    Adrian Paschkowski's avatar
    Adrian Paschkowski committed
            // Sort by closest distance
    
            enemies.Sort((a, b) => (int)Mathf.Sign(Vector3.Distance(transform.position, a.transform.position) - Vector3.Distance(transform.position, b.transform.position)));
    
            currentTargetEnemy = enemies.Count > 0 ? enemies[0] : null;
    
        public override int DealDamage(int dmg)
        {
            var actualDamage = base.DealDamage(dmg);
    
    Adrian Paschkowski's avatar
    Adrian Paschkowski committed
            StatsManager.instance.AddDamageBasedMana(actualDamage, !alive);
    
        public void OnFighterDeath(Fighter fighter)
        {
            enemies.Remove(fighter);
    
            // Wait a short time before targeting next enemy. This is to avoid interrupting the current
            // attack animation, which would happen if we immediately ran to the next target.
            currentTargetEnemy = null;
            Invoke(nameof(CalculateClosestEnemy), delayUntilNextTarget);
    
    
        public override void OnRoundStart()
        {
            base.OnRoundStart();
    
    
    Adrian Paschkowski's avatar
    Adrian Paschkowski committed
            // Listen for Enemy Death events, used for targeting
    
            foreach (var enemy in GameObject.FindGameObjectsWithTag("Enemy"))
            {
                var fighter = enemy.GetComponent<Fighter>();
                fighter.callbacks.Add(this);
                enemies.Add(fighter);
            }
            CalculateClosestEnemy();
        }
    
    
        public override void OnRoundEnd(bool won)
    
    Adrian Paschkowski's avatar
    Adrian Paschkowski committed
            if (!alive) // When the player successfully killed us
    
            {
                damageIndicator.FlashText("Upgrade!", true);
                StatsManager.instance.UpgradeAntiPlayer();
            }
    
            base.OnRoundEnd(won);
    
    
            enemies.Clear();
            currentTargetEnemy = null;
        }