Search Unity

Flee when low on health

Discussion in 'Scripting' started by unity_7UFP4-iCkwsgjg, Jun 23, 2019.

  1. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    Hi everyone, i am trying to make an underwater game using only sea creatures. so far i have my AI purse and attacking each other. I have a health and damage script but what i am trying to achieve is to make the AI shark flee when it's health drops to a certain level. Would anyone be able to help in starting off this ? i can posts my scripts if needed. I am not using Navmesh at the moment I am using Mercuna.
     
  2. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    What aspect are you having trouble with? Detecting if the health is low, or how to flee?
     
  3. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    both. It's health goes down when hit. I can get it to flee upon detection but ideally I only want it to flee when it's health is low
     
  4. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    I assume you have some sort of health script already, with some sort of health value and maximum health value as well? If you divide the health by the max health, it will give you a number between 0 and 1 where 1 is full, 0 is none, 0.5 is half, etc.
    Then you could define low health as:
    (health/max_health) <= 0.2f

    change that 0.2 to whatever you want. This script comparison will check if the health is equal or less than 20%.
     
  5. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    Code (CSharp):
    1. where i would i implement the health/max_health onto my health script ?
    2.  
    3. my health script
    4.  
    5. public ParticleSystem deathParticles;
    6.  
    7.     Animator _anim;
    8.     public string MyTrigger;
    9.     public int maxHealth;
    10.     public int currentHealth;
    11.     public Rigidbody m_rigidBody;
    12.     public GameObject bloodEffect;
    13.  
    14.     void Start()
    15.     {
    16.         currentHealth = maxHealth;
    17.         m_rigidBody = GetComponent<Rigidbody>();
    18.         _anim = GetComponent<Animator>();
    19.     }
    20.  
    21.  
    22.     void Update()
    23.     {
    24.  
    25.     }
    26.  
    27.     public void DamagePlayer(int Hurt, Vector3 direction)
    28.     {
    29.         currentHealth -= Hurt;
    30.         if (currentHealth <= 50)
    31.         {
    32.             currentHealth = 0;
    33.             {
    34.                 _anim.SetTrigger(MyTrigger);
    35.  
    36.             }
    37.  
    38.  
    39.             Instantiate(bloodEffect, transform.position, Quaternion.identity);
    40.             m_rigidBody.isKinematic = true;
    41.             Instantiate(deathParticles, transform.position, Quaternion.identity);
    42.             Destroy(gameObject);
    43.         }
    44.  
    45.     }
     
  6. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    What is the script for your AI?
     
  7. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    what the health or damage script?

    At the moment i want AI to Attack AI. So their is no player at the moment. (Creating an ecosystem)
     
  8. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    You said that you had implemented pursuing a target already, right? You will need to modify that script so that you can switch between your pursuing behavior and your fleeing behavior.
     
  9. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    I am using a behavior tree to allow pursue and flee so how would i edit the script to allow this as so far my shark (see object, pursue then attack and back to wander)
     
  10. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    In that case you want to modify your behavior tree so that you can switch from one to the other. Generally the purposes of a behavior tree is chose which behavior to use at any given time based on conditions, so this is exactly the sort of thing you want to add to your behavior tree. Are you using Opsive Behavior Designer, by any chance?
     
  11. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    im not no i was thinking about getting it but i wouldn't know how to switch from say low health flee ?
     
  12. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    Behavior Designer is the one that I have experience with. Which implementation do you have?
     
  13. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    panda free but looking through behavior designer so will get that one but as that contains pursue and flee but how would i integrate my health script into this to allow fleeing when low health?
     
  14. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    Ah, ok. Fortunately, I've looked at Panda BT before too, when I was evaluating different options. Check out this example in the documentation:

    http://www.pandabehaviour.com/?page_id=23#Implementing_tasks_in_C

    So using this example, we can easily add a Panda BT task to your health script. It would look like this:
    Code (csharp):
    1.  
    2. [TASK]
    3. void CheckLowHealth ()
    4. { if ((((float)currentHealth)/((float)maxHealth))<=0.2 )
    5.   {
    6.       Task.current.Succeed();
    7.   }
    8.   else
    9.   {
    10.       Task.current.Fail();
    11.   }
    12. }
    13.  
    14.  
    Then you can use that check in your behavior tree.
     
    Last edited: Jun 23, 2019
  15. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    and how would i be able to do it if i went with behavior designer?
     
  16. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    Two ways that I can think, of:

    Behavior Designer has it's own template for creating your own task, just like Panda does. Behavior Designer's is more complicated though and you have to inherit from a specific class, so you won't be able to add it to your already-existing Monobehaviour like you can with Panda.
    https://opsive.com/support/documentation/behavior-designer/writing-a-new-conditional-task/

    The more useful way is to use a special type of node that Behavior Designer provides that can receive an event. I that case you could write the same sort of conditional code like above and then call a special event in the behavior tree.
    https://opsive.com/support/documentation/behavior-designer/events/

    It looks like Panda is probably easier for this situation.
     
  17. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    Ah right so i would have change the health and damage scripts make then new conditional tasks?
     
  18. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    If you're talking about Behavior Designer, I'd say that you wouldn't change the health and damage scripts to conditional tasks. You'd still implement the damage and health the same way, but you would make additional scripts to act as conditional tasks.

    I have implemented a health system before (similar to yours) and I opted to use the events instead, though.
     
  19. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    ah right but what would go into the conditional task scripts ?
     
  20. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    Well, if I were implementing this with a Behavior Designer condition task, I would first add a convenient method to your health script, something like:
    Code (csharp):
    1.  
    2. public bool hasLowHealth ()
    3. {
    4.    return ((((float)currentHealth)/((float)maxHealth))<=0.2 );
    5. }
    6.  
    Then, in your custom task, you could get a reference to your health script in the OnAwake function. The Behavior Designer Condition class has a GetComponent, just like mono behaviour.

    In the OnUpdate function, it would look similar to the Panda BT example:

    Code (csharp):
    1.  
    2. public override TaskStatus OnUpdate
    3. {
    4.    if (myHealthScript.hasLowHealth())
    5.    { return (TaskStatus.Success);
    6.    }
    7.   else
    8.   { return (TaskStatus.Failure);
    9.   }
    10. }
    11.  
     
  21. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    ah right would the custom task be my flee ?
     
  22. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    No. When I was talking about the "custom task" in the post above I was only talking about the conditional task to check if the health was low. I hadn't yet gone on to the next step of performing the action. You could also implement that as a custom task if you want to, though.
     
  23. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    ah right so how would i link them on the tree ?
     
  24. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    What does your tree look like now?
     
  25. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    sequence -
    can see object - pursue- attack - set trigger (for animation) then wander
     
  26. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    Ok, so your pursue behavior is a sequence. The flee can be a sequence as well. We just have to set up the tree so that it knows which sequence to run.

    In panda BT, there is a node type called "fallback".
    http://www.pandabehaviour.com/?page_id=23#Fallback
    It will run each of it's children until one succeeds, so it will only run one of it's children:
    So I imagine the structure would be something like this:
    Code (CSharp):
    1.  
    2. Fallback
    3.      Sequence
    4.           CheckLowHealth
    5.           Flee
    6.      Sequence  //Your sequence here
    7.           CanSeeObject
    8.           Pursue
    9.           ...and so on
    10.  
    So first it attempts the first sequence- If the AI has low health, it will execute the first sequence and flee, and it will skip the second sequence. If the AI does not have low health, then the first sequence will fail, and so the Fallback will go on to the second and run that instead.

    If you think about it, the CheckLowHealth works just the same as your CanSeeObject node- in either case it does a simple check and if the check is false, it causes the sequence to fail.
     
  27. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    ah right okay.
    Code (CSharp):
    1. this is my checklow health script
    2.  
    3.         public ParticleSystem deathParticles;
    4.  
    5.         Animator _anim;
    6.         public string MyTrigger;
    7.         public int maxHealth;
    8.         public int currentHealth;
    9.         public Rigidbody m_rigidBody;
    10.         public GameObject bloodEffect;
    11.         public bool HasLowHealth()
    12.         {
    13.             return ((((float)currentHealth) / ((float)maxHealth)) <= 0.2);
    14.         }
    15.  
    16.         void Start()
    17.         {
    18.             m_rigidBody = GetComponent<Rigidbody>();
    19.             _anim = GetComponent<Animator>();
    20.         }
    21.  
    22.  
    23.         void Update()
    24.         {
    25.  
    26.         }
    27.  
    28.  
    29.         public void DamagePlayer(int Hurt, Vector3 direction)
    30.         {
    31.             currentHealth -= Hurt;
    32.             if (currentHealth <= 50)
    33.             {
    34.                 currentHealth = 0;
    35.                 {
    36.                     _anim.SetTrigger(MyTrigger);
    37.  
    38.                 }
    39.  
    40.             }
    41.  
    42.         }
    43.  
    44.     }
     
  28. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    have a sequence set up but it's still not fleeing on low health
     
  29. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
  30. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    I'm Using behavior designer
     
  31. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    You decided to switch behavior tree implementations just because I casually mentioned Behavior Designer in one of my posts?

    What does your tree look like now? By the way, if you are using Behavior Designer, you can still structure your tree the same way as I mentioned above, except I think the "Fallback" node in Panda is called a "Selector" node in Behavior Designer.
     
    Last edited: Jun 24, 2019
  32. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    I researched it early to and it looks more adapt at doing what i want and so far it is working great set up really easy :)
    Still trying to sort the flee when health is low but my tree is :

    sequence
    purse - attack- sequence - health test - flee
     
  33. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    Try a setup like this. Make sure the tree restarts when completed (option on the component).

    Code (csharp):
    1. Selector
    2.     Sequence (Flee)
    3.         Condition (is HP less than 20%?)
    4.         Action    (SetDestination - random Vector3)
    5.     Sequence (Attack)
    6.         Condition (has target?)
    7.         Condition (is distance to target less than 'x'?)
    8.         Action (do attack)
    9.     Sequence (Pursue)
    10.         Condition (has target?)
    11.         Condition (is distance to target greater than 'x'?) (or just 'Invert' the previous distance check node)
    12.         Action (SetDestination)
    13.     Sequence (Idle)
    14.         Action (do nothing...)
    Flee needs to be on the left side, so it's the highest priority. Idle should be far right.
     
  34. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    would i need to place this in my script ((is HP less than 20%?)?
    I am using Mercuna so i wander it retreat in opposite direction then back to wander
     
  35. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    You would have a custom Condition script as shown earlier.

    Code (CSharp):
    1.  
    2. using BehaviorDesigner.Runtime.Tasks;
    3.  
    4. [TaskCategory("My Tasks")]
    5. public class IsHealthLow : Conditional
    6. {
    7.    private HealthScript _healthScript;
    8.  
    9.    public override void OnAwake()
    10.    {
    11.        _healthScript = gameObject.GetComponent<HealthScript>();
    12.    }
    13.  
    14.    public override TaskStatus OnUpdate()
    15.    {
    16.        if (_healthScript.current / _healthScript.max <= 0.2f)
    17.        {
    18.            return TaskStatus.Success;
    19.        }
    20.        else
    21.        {
    22.            return TaskStatus.Failure;
    23.        }
    24.    }
    25. }
    Then also have a similar script for retreat. Use Mercuna's version of SetDestination.
     
  36. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    I can only find for Mercuna (mercuna navigation and wander)
     
  37. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    I don't know anything about Mercuna, but you have your "pursue" implemented already, right? If you imagine that fleeing is simply "pursuing" a safe location, then you could probably reuse a lot of the same logic.
     
  38. unity_7UFP4-iCkwsgjg

    unity_7UFP4-iCkwsgjg

    Joined:
    Dec 13, 2017
    Posts:
    323
    ah right would i need to use the conditonal evaluator on behavour designer?