Pathfinding.MultiTargetPath.RecalculateHTarget C# (CSharp) Method

RecalculateHTarget() public method

public RecalculateHTarget ( bool firstTime ) : void
firstTime bool
return void
		void RecalculateHTarget (bool firstTime) {
			// When pathsForAll is false
			// then no heuristic should be used
			if (!pathsForAll) {
				heuristic = Heuristic.None;
				heuristicScale = 0.0F;
				return;
			}

			// Calculate a new hTarget and rebuild the open list if necessary
			// Rebuilding the open list is necessary when the H score for nodes changes
			switch (heuristicMode) {
			case HeuristicMode.None:
				heuristic = Heuristic.None;
				heuristicScale = 0F;
				break;
			case HeuristicMode.Average:
				if (!firstTime) return;

				// No break
				// The first time the implementation
				// for Average and MovingAverage is identical
				// so we just use fallthrough
				goto case HeuristicMode.MovingAverage;
			case HeuristicMode.MovingAverage:

				// Pick the average position of all nodes that have not been found yet
				var avg = Vector3.zero;
				int count = 0;
				for (int j = 0; j < targetPoints.Length; j++) {
					if (!targetsFound[j]) {
						avg += (Vector3)targetNodes[j].position;
						count++;
					}
				}

				// Should use asserts, but they were first added in Unity 5.1
				// so I cannot use them because I want to keep compatibility with 4.6
				// (as of 2015)
				if (count == 0) throw new System.Exception("Should not happen");

				avg /= count;
				hTarget = (Int3)avg;
				break;
			case HeuristicMode.Midpoint:
				if (!firstTime) return;

				// No break
				// The first time the implementation
				// for Midpoint and MovingMidpoint is identical
				// so we just use fallthrough
				goto case HeuristicMode.MovingMidpoint;
			case HeuristicMode.MovingMidpoint:

				Vector3 min = Vector3.zero;
				Vector3 max = Vector3.zero;
				bool set = false;

				// Pick the median of all points that have
				// not been found yet
				for (int j = 0; j < targetPoints.Length; j++) {
					if (!targetsFound[j]) {
						if (!set) {
							min = (Vector3)targetNodes[j].position;
							max = (Vector3)targetNodes[j].position;
							set = true;
						} else {
							min = Vector3.Min((Vector3)targetNodes[j].position, min);
							max = Vector3.Max((Vector3)targetNodes[j].position, max);
						}
					}
				}

				var midpoint = (Int3)((min+max)*0.5F);
				hTarget = midpoint;
				break;
			case HeuristicMode.Sequential:

				// The first time the hTarget should always be recalculated
				// But other times we can skip it if we have not yet found the current target
				// since then the hTarget would just be set to the same value again
				if (!firstTime && !targetsFound[sequentialTarget]) {
					return;
				}

				float dist = 0;

				// Pick the target which is furthest away and has not been found yet
				for (int j = 0; j < targetPoints.Length; j++) {
					if (!targetsFound[j]) {
						float d = (targetNodes[j].position-startNode.position).sqrMagnitude;
						if (d > dist) {
							dist = d;
							hTarget = (Int3)targetPoints[j];
							sequentialTarget = j;
						}
					}
				}
				break;
			}

			// Rebuild the open list since all the H scores have changed
			// However the first time we can skip this since
			// no nodes are added to the heap yet
			if (!firstTime) {
				RebuildOpenList();
			}
		}