Search Unity

How do I setup my enemy to attack player or my companions?

Discussion in 'Scripting' started by Pixitales, May 28, 2019.

  1. Pixitales

    Pixitales

    Joined:
    Oct 24, 2018
    Posts:
    227
    Right now it can target and attack the player. How do I make my enemy attack my companions too? Should I just duplicate the set target and hurt player function and rename it to my companion name?

    Here is my enemy script, its connected to multiple scripts and managers. A lot of other stuff you can just ignore too:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Enemy : NPC
    6. {
    7.     [SerializeField]
    8.     private CanvasGroup healthGroup; //Show enemy health bar when selected
    9.  
    10.     [SerializeField]
    11.     private GameObject bloodSplash;
    12.  
    13.     private Transform zombieTarget;
    14.  
    15.     private IState currentState;
    16.  
    17.     //Get Components
    18.     private Collider2D enemyCollider;
    19.     private SpriteRenderer sprite;
    20.  
    21.     [SerializeField]
    22.     private LootTable lootTable;
    23.  
    24.     public float MyAttackRange { get; set; }
    25.  
    26.     public float MyAttackTime { get; set; }
    27.  
    28.     public Vector3 MyStartPosition { get; set; }
    29.  
    30.     [SerializeField]
    31.     private float initAggroRange;
    32.  
    33.     public float MyAggroRange { get; set; }
    34.  
    35.     public bool InRange
    36.     {
    37.         get
    38.         {
    39.             return Vector2.Distance(transform.position, MyTarget.position) < MyAggroRange;
    40.         }
    41.     }
    42.  
    43.     public bool isPatrolling = true;
    44.     public bool isAlive = true;
    45.     public bool isAttacking = false;
    46.  
    47.     private float timeBetweenMove = 1;
    48.     private float timeBetweenMoveCounter;
    49.     private float timeToMove = 2;
    50.     private float timeToMoveCounter;
    51.  
    52.     public GameObject prefab;
    53.  
    54.  
    55.     protected void Awake()
    56.     {
    57.         MyStartPosition = transform.position; //Set enemy start position
    58.         MyAggroRange = initAggroRange;
    59.         MyAttackRange = 1; //Enemy Attack Range
    60.         ChangeState(new IdleState());
    61.     }
    62.  
    63.  
    64.     protected override void Update()
    65.     {
    66.         if (IsAlive)
    67.         {
    68.             if (!IsUsingSkill)
    69.             {
    70.                 MyAttackTime += Time.deltaTime;
    71.             }
    72.  
    73.             currentState.Update();
    74.         }
    75.  
    76.         base.Update();
    77.  
    78.         if (!isAttacking)
    79.         {
    80.             RandomMovement();
    81.         }
    82.     }
    83.  
    84.  
    85.     public override Transform Select()
    86.     {
    87.         healthGroup.alpha = 1;
    88.  
    89.         return base.Select();
    90.     }
    91.  
    92.     public override void DeSelect()
    93.     {
    94.         healthGroup.alpha = 0;
    95.  
    96.         base.DeSelect();
    97.     }
    98.  
    99.     public void RandomMovement()
    100.     {
    101.         if (isPatrolling && isAlive)
    102.         {
    103.             timeToMoveCounter -= Time.deltaTime;
    104.             MyRigidbody.velocity = Direction;
    105.  
    106.             if (timeToMoveCounter < 0f)
    107.             {
    108.                 isPatrolling = false;
    109.                 timeBetweenMoveCounter = Random.Range(timeBetweenMove * 0.75f, timeBetweenMove * 1.25f);
    110.             }
    111.         }
    112.         else
    113.         {
    114.             timeBetweenMoveCounter -= Time.deltaTime;
    115.             MyRigidbody.velocity = Vector2.zero;
    116.  
    117.             if (timeBetweenMoveCounter < 0f)
    118.             {
    119.                 isPatrolling = true;
    120.                 timeToMoveCounter = Random.Range(timeToMove * 0.75f, timeBetweenMove * 1.25f);
    121.  
    122.                 //Direction = Random.insideUnitSphere;
    123.  
    124.                 Direction = new Vector3(Random.Range(-1f, 1f) * MoveSpeed, Random.Range(-1f, 1f) * MoveSpeed, 0f).normalized;
    125.  
    126.                 //MyRigidbody.AddForce(new Vector3(Direction.x, Direction.y, 0f));
    127.             }
    128.         }
    129.     }
    130.  
    131.  
    132.     public override void TakeDamage(float damage, Transform source) //Make enemy take damage when hit
    133.     {
    134.         if (!(currentState is EvadeState && isAlive)) //if (health.MyCurrentValue > 0)
    135.         {
    136.             SetTarget(source);
    137.  
    138.             base.TakeDamage(damage, source);
    139.  
    140.             OnHealthChanged(health.MyCurrentValue);
    141.  
    142.             //Blood Splash
    143.             Instantiate(bloodSplash, transform.position, Quaternion.identity);
    144.  
    145.             StartCoroutine("DamageFlash");
    146.  
    147.             Select(); //Show health bar
    148.  
    149.             if (health.MyCurrentValue <= 0)
    150.             {
    151.                 isPatrolling = false;
    152.  
    153.                 isAlive = false;
    154.  
    155.                 enemyCollider = GetComponent<Collider2D>();
    156.                 enemyCollider.enabled = false;
    157.  
    158.                 //GetComponent<SpriteRenderer>().material.color = Color.gray;
    159.                 sprite = GetComponent<SpriteRenderer>();
    160.                 sprite.sortingOrder = -1;
    161.  
    162.                 DeSelect(); //Hide health bar
    163.             }
    164.         }
    165.     }
    166.  
    167.     public void ChangeState(IState newState) //Change the enemys state
    168.     {
    169.         if (currentState != null)
    170.         {
    171.             currentState.Exit();
    172.         }
    173.  
    174.         currentState = newState;
    175.  
    176.         currentState.Enter(this);
    177.     }
    178.  
    179.     public void SetTarget(Transform target)
    180.     {
    181.         if (MyTarget == null && !(currentState is EvadeState))
    182.         {
    183.             float distance = Vector2.Distance(transform.position, target.position);
    184.             MyAggroRange = initAggroRange;
    185.             MyAggroRange += distance;
    186.             MyTarget = target;
    187.         }
    188.     }
    189.  
    190.     public void Reset()
    191.     {
    192.         this.MyTarget = null;
    193.         this.MyAggroRange = initAggroRange;
    194.         this.MyHealth.MyCurrentValue = this.MyHealth.MyMaxValue;
    195.         OnHealthChanged(health.MyCurrentValue);
    196.     }
    197.  
    198.     public override void Interact() //Interact with enemy
    199.     {
    200.         if (!IsAlive)
    201.         {
    202.             lootTable.ShowLoot();
    203.         }
    204.     }
    205.  
    206.     public IEnumerator DamageFlash() //Change color
    207.     {
    208.         if (health.MyCurrentValue > 0)
    209.         {
    210.             GetComponent<SpriteRenderer>().material.color = new Color32(255, 160, 171, 255); //Pink
    211.             yield return new WaitForSeconds(0.3f);
    212.             GetComponent<SpriteRenderer>().material.color = Color.white;
    213.             yield return new WaitForSeconds(0.3f);
    214.         }
    215.         else
    216.         {
    217.             float infectedChance = Random.Range(0f, 1f);
    218.  
    219.             if (infectedChance > 0.3f)
    220.             {
    221.                 GetComponent<SpriteRenderer>().material.color = Color.green;
    222.  
    223.                 StartCoroutine("Infected");
    224.             }
    225.             else
    226.             {
    227.                 GetComponent<SpriteRenderer>().material.color = Color.gray;
    228.             }
    229.         }
    230.     }
    231.  
    232.     public IEnumerator Infected()
    233.     {
    234.         yield return new WaitForSeconds(3);
    235.  
    236.         GameObject gameObject = Instantiate<GameObject>(prefab, transform.position, prefab.transform.rotation);
    237.  
    238.         Destroy(this.gameObject);
    239.     }
    240. }
    241.  
     
  2. adibichea

    adibichea

    Joined:
    Jul 15, 2015
    Posts:
    73
    By changing target and duplicate your enemy code to your companion. Then delete/change useless functionality for companions, like: movement.
    After everything works, rebuild your character/companion classes to derive from a class.. or just your companion can derive from character class.

    Code (CSharp):
    1.  SetTarget(companion.transform);
    funny to see
    Code (CSharp):
    1. public class Enemy : NPC
    NPC = non playing character
     
  3. Pixitales

    Pixitales

    Joined:
    Oct 24, 2018
    Posts:
    227
    thanks I will try that. My scripts is kinda a mess at the moment and there are stuff I need from NPC script. Lots of moving codes around lol.
     
  4. Pixitales

    Pixitales

    Joined:
    Oct 24, 2018
    Posts:
    227
    The way how i setup for the enemy to select a target is enter trigger 2d. You think player and companion share the same tag will work?
     
  5. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,638
    It doesn't look like you are checking the tags anywhere. Right now it looks like you're calling SetTarget on whatever transform is your "source" of damage. So it should already work on both the player and companion, right? The only thing that matters is which on Damages the enemy last. (unless I'm misreading your code)
     
  6. Pixitales

    Pixitales

    Joined:
    Oct 24, 2018
    Posts:
    227
    Yeah bc I didn't post it there. Everything is working properly and linked to different scripts. The script says tiggerenter2D.... if tag = player then get enemy parent to set target. The script is attached on a big circle collider which also used for aggro range.
     
  7. Pixitales

    Pixitales

    Joined:
    Oct 24, 2018
    Posts:
    227
    I tried it and added a bunch of codes to check (i.e player or ally and access a specific script). I got a null reference for target. Its really bad coding and messy anyways. I did for find an easier way. All it takes is 2 lines of code which is way more efficient. First line is get the tag:

    Code (CSharp):
    1. if (collision.tag == "Player" || collision.tag == "Ally")
    Put a damage function in your ally and player script with the same exact word by word

    Add this to your enemy attack
    Code (CSharp):
    1. MyTarget.SendMessage("HurtPlayer", DamageToGive);
    Since the Player and Ally both have the same damage function. Either one can take damage when being attacked. Its working great.