// Add and removes references to current and neighboring sectors // as this component moves around the world. private void _MembershipChanged(List <SECTR_Sector> left, List <SECTR_Sector> joined) { // Add ref to all of the new objects first so that we don't unload and then immeditately load again. if (joined != null) { int numJoined = joined.Count; for (int sectorIndex = 0; sectorIndex < numJoined; ++sectorIndex) { SECTR_Sector sector = joined[sectorIndex]; if (sector && !currentSectors.Contains(sector)) { SECTR_Graph.BreadthWalk(ref neighbors, sector, 0, MaxDepth); int numNeighbors = neighbors.Count; for (int neighborIndex = 0; neighborIndex < numNeighbors; ++neighborIndex) { SECTR_Chunk neighborChunk = neighbors[neighborIndex].Sector.GetComponent <SECTR_Chunk>(); if (neighborChunk) { neighborChunk.AddReference(); } } currentSectors.Add(sector); } } } // Dec ref any sectors we're no longer in. if (left != null) { int numLeft = left.Count; for (int sectorIndex = 0; sectorIndex < numLeft; ++sectorIndex) { SECTR_Sector sector = left[sectorIndex]; // We have to be careful about double-removing on shutdown b/c we don't control // order of destruction. if (sector && currentSectors.Contains(sector)) { SECTR_Graph.BreadthWalk(ref neighbors, sector, 0, MaxDepth); int numNeighbors = neighbors.Count; for (int neighborIndex = 0; neighborIndex < numNeighbors; ++neighborIndex) { SECTR_Chunk neighborChunk = neighbors[neighborIndex].Sector.GetComponent <SECTR_Chunk>(); if (neighborChunk) { neighborChunk.RemoveReference(); } } currentSectors.Remove(sector); } } } }
void Update() { if (waypoints.Count == 0 && SECTR_Sector.All.Count > 0 && MovementSpeed > 0f) { SECTR_Sector goal = SECTR_Sector.All[Random.Range(0, SECTR_Sector.All.Count)]; SECTR_Graph.FindShortestPath(ref path, transform.position, goal.transform.position, SECTR_Portal.PortalFlags.Locked); Vector3 height = Vector3.zero; Collider myCollider = GetComponent <Collider>(); if (myCollider) { height.y += myCollider.bounds.extents.y; } waypoints.Clear(); int numNodes = path.Count; for (int nodeIndex = 0; nodeIndex < numNodes; ++nodeIndex) { SECTR_Graph.Node node = path[nodeIndex]; waypoints.Add(node.Sector.transform.position + height); if (node.Portal) { waypoints.Add(node.Portal.transform.position); } } waypoints.Add(goal.transform.position + height); currentWaypointIndex = 0; } if (waypoints.Count > 0 && MovementSpeed > 0) { Vector3 nextWaypoint = waypoints[currentWaypointIndex]; Vector3 vecToGoal = nextWaypoint - transform.position; float sqrGoalDistance = vecToGoal.sqrMagnitude; if (sqrGoalDistance > SECTR_Geometry.kVERTEX_EPSILON) { float distanceToGoal = Mathf.Sqrt(sqrGoalDistance); vecToGoal /= distanceToGoal; vecToGoal *= Mathf.Min(MovementSpeed * Time.deltaTime, distanceToGoal); transform.position += vecToGoal; } else { ++currentWaypointIndex; if (currentWaypointIndex >= waypoints.Count) { waypoints.Clear(); } } } }
/// Writes out the current scene's Sector/Portal graph as a .dot file /// which can be visualized in programs like GraphVis and the like. public static void WriteGraphDot() { if (!string.IsNullOrEmpty(EditorApplication.currentScene)) { string sceneDir; string sceneName; SECTR_Asset.GetCurrentSceneParts(out sceneDir, out sceneName); sceneName = sceneName.Replace(".unity", ""); string graphFile = SECTR_Graph.GetGraphAsDot(sceneName); string path = sceneDir + sceneName + "_SECTR_Graph.dot"; File.WriteAllText(SECTR_Asset.UnityToOSPath(path), graphFile); AssetDatabase.Refresh(); Selection.activeObject = AssetDatabase.LoadMainAssetAtPath(path); EditorUtility.FocusProjectWindow(); } }