Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to detect when the target is right above the agent?

Discussion in 'Navigation' started by MinhocaNice, Nov 11, 2020.

  1. MinhocaNice

    MinhocaNice

    Joined:
    May 3, 2020
    Posts:
    249
    In my zombie game I realised I could avoid zombies entirely by simply sitting on top of their heads the whole time. Once I am on them they can never reach me unless I jump out.

    One funny and stupid solution would be to remove the zombies from the "Solid" layer so the character controller thinks the player is falling why they are on top of them, thus dying as soon as they reach the floor (or at least taking a lot of fall damage).

    But my best solution was to make it possible for zombies to attack players on top of them. However, I can't figure out how to do so because the most obvious solution doesn't seem to work:

    Code (CSharp):
    1.         if (Player[TargetNum].position.y > transform.position.y + 1f)
    2.         {
    3.             Enemy.UpwardAttack (TargetNum);
    4.         }
    5.         else
    6.         {
    7.             Enemy.ForwardAttack (TargetNum);
    8.         }
    The forward attack script works fine but for some reason the upward does not. I checked the other parts of the script and they all seem to be working like they should, except for this one. Any solutions?
     
  2. MinhocaNice

    MinhocaNice

    Joined:
    May 3, 2020
    Posts:
    249
    Any ideas?
     
  3. Skynet766

    Skynet766

    Joined:
    Sep 13, 2020
    Posts:
    22
  4. MinhocaNice

    MinhocaNice

    Joined:
    May 3, 2020
    Posts:
    249
    Trying that right now...
     
  5. MinhocaNice

    MinhocaNice

    Joined:
    May 3, 2020
    Posts:
    249
    It didn't work, no line was drawn for what I have seen. What is weird though is that the forward attack didn't draaw any lines either, even though it is working fine.

    Script:


    Code (CSharp):
    1.     public void ForwardAttack(int TargetNum)
    2.     {
    3.         if (AttackCooldown <= 0f)
    4.         {
    5.             AttackCooldown = 1f / AttackSpeed;
    6.             CurrentSpeed = AttackingSpeed;
    7.             CurrentAngularSpeed = AttackingAngularSpeed;
    8.  
    9.             Debug.DrawLine(transform.position, transform.position + new Vector3(0f, 0f, ForwardAttackReach), Color.red);
    10.             StartCoroutine(AttackHit(TargetNum, 0));
    11.         }
    12.     }
    13.  
    14.     public void UpwardAttack(int TargetNum)
    15.     {
    16.         if (AttackCooldown <= 0f)
    17.         {
    18.             AttackCooldown = 1f / AttackSpeed;
    19.             CurrentSpeed = AttackingSpeed;
    20.             CurrentAngularSpeed = AttackingAngularSpeed;
    21.  
    22.             Debug.DrawLine(transform.position, transform.position + new Vector3(0f, UpwardAttackReach, 0f), Color.red);
    23.             StartCoroutine(AttackHit(TargetNum, 1));
    24.         }
    25.     }
    26.  
    27.     IEnumerator AttackHit(int TargetNum, int AttackPosition)
    28.     {
    29.         yield return new WaitForSeconds(AttackDelay);
    30.  
    31.         switch (AttackPosition)
    32.         {
    33.             case 0:
    34.                 if (Physics.Raycast(transform.position, transform.forward, ForwardAttackReach))
    35.                 {
    36.                     if (TargetStats != null)
    37.                     {
    38.                         TargetStats [TargetNum].Hurt(AttackDamage);
    39.                         Debug.Log(this.name + " hit player " + TargetNum);
    40.                     }
    41.                 }
    42.             break;
    43.  
    44.             case 1:
    45.                 if (Physics.Raycast(transform.position, transform.up, UpwardAttackReach))
    46.                 {
    47.                     Debug.DrawLine(transform.position, transform.position + new Vector3(0f, UpwardAttackReach, 0f), Color.red);
    48.  
    49.                     if (TargetStats != null)
    50.                     {
    51.                         TargetStats [TargetNum].Hurt(AttackDamage);
    52.                         Debug.Log(this.name + " hit player " + TargetNum);
    53.                     }
    54.                 }
    55.             break;
    56.         }
    57.  
    58.         CurrentSpeed = Speed;
    59.         CurrentAngularSpeed = AngularSpeed;
    60.     }
    EDIT: After a bit of testing I noticed the Forward attack lines do show up but for a brief fraction of a second, and in a very weird orientation, which now that I think about it make sense.
     
    Last edited: Nov 17, 2020
  6. Skynet766

    Skynet766

    Joined:
    Sep 13, 2020
    Posts:
    22
    You can specify a duration for the line to stay visible. By default, it is a single frame.

    Also I would put the line render inside the code that determines whether to attack (so always draw the "up" line)

    You are drawing the line in the attack method, which doesn't help because the issue is the zombie isn't doing the attack when you want. The line helps you see what the game was "thinking". For example if the line pokes into the player, that means the zombie is shorter than you think and that's why the player doesn't count as "above" the zombie.
     
  7. MinhocaNice

    MinhocaNice

    Joined:
    May 3, 2020
    Posts:
    249
    Ah I see. But if we already know what the problem is then why bother drawing the line? How do I make so the zombie actually does the attack?
     
  8. Skynet766

    Skynet766

    Joined:
    Sep 13, 2020
    Posts:
    22
    We don't know if that's definitely the bug, that's why you draw the line to check.
     
  9. MinhocaNice

    MinhocaNice

    Joined:
    May 3, 2020
    Posts:
    249
    Sorry late reply. Yeah I still wasn't able to get around this.

    It has been a while I check this part of my script, but I wasn't able to make the lines work properly. Instead I just added Gizmos.DrawLine so I check the range of the attacks.

    I will try what you said but I feel it's redundant, if the attack isn't being called anyway the line won't really show me anything.