123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- using UnityEngine;
- using UnityEngine.Profiling;
- namespace Pathfinding.RVO {
- using Pathfinding.Util;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [ExecuteInEditMode]
- [AddComponentMenu("Pathfinding/Local Avoidance/RVO Simulator")]
- [HelpURL("http://arongranberg.com/astar/documentation/stable/class_pathfinding_1_1_r_v_o_1_1_r_v_o_simulator.php")]
- public class RVOSimulator : VersionedMonoBehaviour {
-
- public static RVOSimulator active { get; private set; }
-
-
-
-
-
-
- [Tooltip("Desired FPS for rvo simulation. It is usually not necessary to run a crowd simulation at a very high fps.\n" +
- "Usually 10-30 fps is enough, but can be increased for better quality.\n"+
- "The rvo simulation will never run at a higher fps than the game")]
- public int desiredSimulationFPS = 20;
-
-
-
-
-
- [Tooltip("Number of RVO worker threads. If set to None, no multithreading will be used.")]
- public ThreadCount workerThreads = ThreadCount.Two;
-
-
-
-
-
-
-
-
-
- [Tooltip("Calculate local avoidance in between frames.\nThis can increase jitter in the agents' movement so use it only if you really need the performance boost. " +
- "It will also reduce the responsiveness of the agents to the commands you send to them.")]
- public bool doubleBuffering;
-
- [Tooltip("Bias agents to pass each other on the right side.\n" +
- "If the desired velocity of an agent puts it on a collision course with another agent or an obstacle " +
- "its desired velocity will be rotated this number of radians (1 radian is approximately 57°) to the right. " +
- "This helps to break up symmetries and makes it possible to resolve some situations much faster.\n\n" +
- "When many agents have the same goal this can however have the side effect that the group " +
- "clustered around the target point may as a whole start to spin around the target point.")]
- [Range(0, 0.2f)]
- public float symmetryBreakingBias = 0.1f;
-
-
-
-
- [Tooltip("Determines if the XY (2D) or XZ (3D) plane is used for movement")]
- public MovementPlane movementPlane = MovementPlane.XZ;
-
-
-
-
-
-
- public bool drawObstacles;
-
- Pathfinding.RVO.Simulator simulator;
-
-
-
-
- public Simulator GetSimulator () {
- if (simulator == null) {
- Awake();
- }
- return simulator;
- }
- void OnEnable () {
- active = this;
- }
- protected override void Awake () {
- base.Awake();
-
-
- active = this;
- if (simulator == null && Application.isPlaying) {
- int threadCount = AstarPath.CalculateThreadCount(workerThreads);
- simulator = new Pathfinding.RVO.Simulator(threadCount, doubleBuffering, movementPlane);
- }
- }
-
- void Update () {
- if (!Application.isPlaying) return;
- if (desiredSimulationFPS < 1) desiredSimulationFPS = 1;
- var sim = GetSimulator();
- sim.DesiredDeltaTime = 1.0f / desiredSimulationFPS;
- sim.symmetryBreakingBias = symmetryBreakingBias;
- sim.Update();
- }
- void OnDestroy () {
- active = null;
- if (simulator != null) simulator.OnDestroy();
- }
- #if UNITY_EDITOR
- [System.NonSerialized]
- RetainedGizmos gizmos = new RetainedGizmos();
- static Color ObstacleColor = new Color(255/255f, 60/255f, 15/255f, 1.0f);
- void OnDrawGizmos () {
-
- if (Event.current.type != EventType.Repaint) return;
- if (drawObstacles && simulator != null && simulator.obstacles != null) {
- var hasher = new RetainedGizmos.Hasher();
- var obstacles = simulator.obstacles;
- int numEdges = 0;
- for (int i = 0; i < obstacles.Count; i++) {
- var vertex = obstacles[i];
- do {
- hasher.AddHash(vertex.position.GetHashCode() ^ vertex.height.GetHashCode());
- numEdges++;
- vertex = vertex.next;
- } while (vertex != obstacles[i] && vertex != null);
- }
- if (!gizmos.Draw(hasher)) {
- Profiler.BeginSample("Rebuild RVO Obstacle Gizmos");
- using (var helper = gizmos.GetGizmoHelper(null, hasher)) {
- var up = movementPlane == MovementPlane.XY ? Vector3.back : Vector3.up;
- var vertices = new Vector3[numEdges*6];
- var colors = new Color[numEdges*6];
- int edgeIndex = 0;
- for (int i = 0; i < obstacles.Count; i++) {
- var start = obstacles[i];
- var c = start;
- do {
- vertices[edgeIndex*6 + 0] = c.position;
- vertices[edgeIndex*6 + 1] = c.next.position;
- vertices[edgeIndex*6 + 2] = c.next.position + up*c.next.height;
- vertices[edgeIndex*6 + 3] = c.position;
- vertices[edgeIndex*6 + 4] = c.next.position + up*c.next.height;
- vertices[edgeIndex*6 + 5] = c.position + up*c.height;
- edgeIndex++;
- c = c.next;
- } while (c != start && c != null && c.next != null);
- }
- for (int i = 0; i < colors.Length; i++) {
- colors[i] = ObstacleColor;
- }
- helper.DrawTriangles(vertices, colors, numEdges * 2);
- }
- Profiler.EndSample();
- }
- gizmos.FinalizeDraw();
- }
- }
- void OnDisable () {
- gizmos.ClearCache();
- }
- #endif
- }
- }
|