SHARE
TWEET

Untitled

a guest Aug 19th, 2017 104 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using UnityEngine;
  2. using System.Collections;
  3. using Pathfinding;
  4. using Pathfinding.RVO;
  5.  
  6. /** Starcraft 2-like avoidance.
  7.  * The main idea for this script is to
  8.  * - Reduce the local avoidance priority for agents that have reached their destination once.
  9.  * - Make agents stop if there is a high density of units around its destination.
  10.  *
  11.  * 'High density' is defined as:
  12.  * Take the circle with the center at the AI's destination and a radius such that the AI's current position
  13.  * is touching its border. Let 'A' be the area of that circle. Further let 'a' be the total area of all
  14.  * individual agents inside that circle.
  15.  * The agent should stop if a > A*0.6 or something like that. I.e if the agents inside the circle cover
  16.  * over 60% of the surface of the circle. The 60% figure can be modified.
  17.  */
  18. public class SC2Avoidance : MonoBehaviour {
  19.     IAstarAI ai;
  20.     RVOController rvo;
  21.  
  22.     void Awake () {
  23.         ai = GetComponent<IAstarAI>();
  24.         rvo = GetComponent<RVOController>();
  25.     }
  26.  
  27.     float timer1 = 0;
  28.     Vector3 prevDestination;
  29.     bool reachedCurrentDestination;
  30.  
  31.     bool ShouldStop () {
  32.         var agents = rvo.simulator.GetAgents();
  33.         var thisAgent = rvo.rvoAgent;
  34.         var radius = (ai.destination - ai.position).magnitude;
  35.         var accArea = 0f;
  36.  
  37.         foreach (var agent in agents) {
  38.             var distToDestination = (rvo.To2D(ai.destination) - agent.Position).magnitude;
  39.             if (distToDestination < radius + agent.radius * 0.75f) {
  40.                 accArea += agent.Radius*agent.Radius*Mathf.PI;
  41.             }
  42.         }
  43.  
  44.         bool result = accArea > radius*radius*Mathf.PI*0.60f;
  45.         Pathfinding.Util.Draw.Debug.CircleXZ(ai.destination, radius, result ? Color.green : Color.red);
  46.         return result;
  47.     }
  48.    
  49.     void Update () {
  50.         if (ai.destination != prevDestination) {
  51.             timer1 = float.PositiveInfinity;
  52.             reachedCurrentDestination = false;
  53.         }
  54.         prevDestination = ai.destination;
  55.  
  56.         if (ai.targetReached || ShouldStop()) {
  57.             if (!ai.pathPending) {
  58.                 timer1 = 0f;
  59.                 reachedCurrentDestination = true;
  60.             }
  61.             ai.isStopped = true;
  62.             rvo.priority = Mathf.Lerp(rvo.priority, 0.05f, Time.deltaTime * 2);
  63.         } else {
  64.             timer1 += Time.deltaTime;
  65.  
  66.             if (timer1 > 3) {
  67.                 ai.isStopped = false;
  68.                 if (reachedCurrentDestination) {
  69.                     rvo.priority = Mathf.Lerp(rvo.priority, 0.1f, Time.deltaTime * 2);
  70.                 } else {
  71.                     rvo.priority = Mathf.Lerp(rvo.priority, 0.5f, Time.deltaTime * 4);
  72.                 }
  73.             }
  74.         }
  75.     }
  76. }
RAW Paste Data
Top