private void LoadStepStates() { List <BridgeStep> list = new List <BridgeStep>(); int num = 0; for (int i = 0; i < this.steps.Count; i++) { HingeJoint component = this.steps[i].GetComponent <HingeJoint>(); if (component) { num++; } BridgeStep component2 = this.steps[i].GetComponent <BridgeStep>(); if (component2) { list.Add(component2); } } if (this.endPoint.GetComponent <HingeJoint>()) { num++; } if (num == this.steps.Count + 1) { return; } for (int j = 0; j < list.Count; j++) { list[j].LoadState(); } BridgeStep component3 = this.endPoint.GetComponent <BridgeStep>(); if (component3) { component3.LoadState(); } }
public void OnDataLoaded() { this.stepParent = base.transform.Find("StepParent"); this.endPoint = base.transform.Find("EndPoint"); if (this.stepPrefab == null || this.endPoint == null) { return; } Vector3 vector = this.endPoint.position - base.transform.position; float magnitude = vector.magnitude; float f = magnitude / (this.stepLength + this.stepGap); this.steps = new List <Transform>(); for (int i = 0; i < this.stepParent.childCount; i++) { Transform child = this.stepParent.GetChild(i); this.steps.Add(child); } int num = this.steps.Count - Mathf.FloorToInt(f); if (num > 0) { for (int j = 0; j < num; j++) { UnityEngine.Object.DestroyImmediate(this.steps[this.steps.Count - 1].gameObject); this.steps.RemoveAt(this.steps.Count - 1); } } int num2 = 0; while (this.steps.Count < Mathf.FloorToInt(f) && num2 <= 100) { GameObject gameObject = UnityEngine.Object.Instantiate <GameObject>(this.stepPrefab); gameObject.transform.parent = this.stepParent; gameObject.name = string.Format("Step{0:000}", this.steps.Count); this.steps.Add(gameObject.transform); num2++; } HingeJoint hingeJoint = null; for (int k = 0; k < this.steps.Count; k++) { this.steps[k].localPosition = Vector3.right * ((float)k * (this.stepLength + this.stepGap) + (this.stepLength + this.stepGap) * 0.5f); this.steps[k].localRotation = Quaternion.identity; HingeJoint component = this.steps[k].GetComponent <HingeJoint>(); if (hingeJoint != null) { component.connectedBody = hingeJoint.GetComponent <Rigidbody>(); } component.autoConfigureConnectedAnchor = true; hingeJoint = component; } Transform transform = base.transform.Find("StepRopeParent"); if (transform != null) { UnityEngine.Object.DestroyImmediate(transform.gameObject); } if (transform == null) { transform = new GameObject("StepRopeParent").transform; transform.parent = base.transform; } transform.localPosition = Vector3.zero; if (this.stepRopes == null) { this.stepRopes = new List <GameObject>(); } this.stepRopes.Clear(); for (int l = 0; l < this.steps.Count + 1; l++) { GameObject gameObject2 = UnityEngine.Object.Instantiate <GameObject>(this.stepRopePrefab); gameObject2.name = string.Format("StepRope{0:000}", l); gameObject2.transform.parent = transform; if (l < this.steps.Count) { gameObject2.transform.position = this.steps[l].position; } else { gameObject2.transform.position = this.endPoint.position; } this.stepRopes.Add(gameObject2); } for (int m = 0; m < this.stepParent.childCount; m++) { Transform child2 = this.stepParent.GetChild(m); HingeJoint component2 = child2.GetComponent <HingeJoint>(); if (component2 && this.stepBreakForces.Count > m) { component2.breakForce = this.stepBreakForces[m]; if (this.stepBreakForces[m] < 0.1f) { this.isBroken = true; } } } Transform transform2 = this.steps[this.steps.Count - 1]; HingeJoint component3 = this.endPoint.GetComponent <HingeJoint>(); component3.connectedBody = transform2.GetComponent <Rigidbody>(); float d = Mathf.Atan2(vector.y, vector.x) * 57.29578f; this.stepParent.localEulerAngles = Vector3.forward * d; this.endPoint.position = transform2.position + transform2.right * (this.stepLength * 0.5f + this.stepGap); base.transform.rotation = Quaternion.identity; if (Application.isPlaying) { foreach (Transform transform3 in this.steps) { BridgeStep bridgeStep = transform3.GetComponent <BridgeStep>(); LevelRigidbody component4 = transform3.GetComponent <LevelRigidbody>(); if (component4) { UnityEngine.Object.DestroyImmediate(component4); } if (!bridgeStep) { bridgeStep = transform3.gameObject.AddComponent <BridgeStep>(); } bridgeStep.Init(false); } LevelRigidbody component5 = this.endPoint.GetComponent <LevelRigidbody>(); if (component5) { UnityEngine.Object.DestroyImmediate(component5); } BridgeStep bridgeStep2 = this.endPoint.GetComponent <BridgeStep>(); if (!bridgeStep2) { bridgeStep2 = this.endPoint.gameObject.AddComponent <BridgeStep>(); } bridgeStep2.Init(true); } this.SubscribeToJointBreaks(); }
/// <summary> /// Search a path with HPA algorithm /// </summary> /// <param name="_Start">Tile to start from</param> /// <param name="_End">Tile to reach</param> /// <param name="_ChronoInfos">Struct with times value to evaluate performance</param> /// <param name="_MaxSeconds">Max time allowed to search a solution. If value is negative, no time limit applied</param> /// <returns>the shortest path from start tile to end tile if it exists, null otherwise</returns> public static Path SearchHPAFromTo(GridClustered _GridClustered, Tile _Start, Tile _End, out ChronoInfos _ChronoInfos, float _MaxSeconds) { StartChrono(); if (_Start == null || !_Start.IsAccessible || _End == null || !_End.IsAccessible || _GridClustered == null) { _ChronoInfos = ChronoInfos.InfosNone; return(null); } Cluster startCluster = _GridClustered.GetClusterOfTile(_Start); Cluster endCluster = _GridClustered.GetClusterOfTile(_End); Path instantSolution = null; if (startCluster == endCluster && (instantSolution = startCluster.ComputeInternalPathFromTo(_Start, _End)) != null) { _ChronoInfos = StopChrono(_Start, _End, true); return(instantSolution); } List <BridgeStep> openList = new List <BridgeStep>(); CustomComparer <BridgeStep> comparer = new CustomComparer <BridgeStep>(false); HashSet <Bridge> closeSet = new HashSet <Bridge>(); // store all the possible bridges connected to the start tile with their path // populate the open list with these bridges as all possible first steps Dictionary <Tile, Path> allFirstParts = new Dictionary <Tile, Path>(); for (int i = 0; i < startCluster.Bridges.Count; i++) { Path path = startCluster.ComputeInternalPathFromTo(_Start, startCluster.Bridges[i].Start); if (path != null) { allFirstParts.Add(startCluster.Bridges[i].Start, path); BridgeStep stepToAdd = new BridgeStep(startCluster.Bridges[i], path.Weight); int indexInsertion = openList.BinarySearch(stepToAdd, comparer); if (indexInsertion < 0) { indexInsertion = ~indexInsertion; } openList.Insert(indexInsertion, stepToAdd); } } // store all the possible bridges connected to the end tile with their path Dictionary <Tile, Path> allLastParts = new Dictionary <Tile, Path>(); for (int i = 0; i < endCluster.Bridges.Count; i++) { Path path = endCluster.ComputeInternalPathFromTo(endCluster.Bridges[i].Start, _End); if (path != null) { allLastParts.Add(endCluster.Bridges[i].Start, path); } } while (openList.Count > 0) { if (_MaxSeconds > 0 && chrono.Elapsed.TotalSeconds > _MaxSeconds) { _ChronoInfos = StopChrono(_Start, _End, false); return(null); } BridgeStep stepToExtend = openList.Last(); removeFromOpenChrono -= chrono.ElapsedMilliseconds; openList.RemoveAt(openList.Count - 1); removeFromOpenChrono += chrono.ElapsedMilliseconds; // if the step is already marked as solution, then it's the shortest solution if (stepToExtend.ReachedGoal) { // recreate whole path createSolutionChrono -= chrono.ElapsedMilliseconds; Path solution = stepToExtend.CreateCompletePath(_GridClustered, allFirstParts, allLastParts); createSolutionChrono += chrono.ElapsedMilliseconds; _ChronoInfos = StopChrono(_Start, _End, true); return(solution); } Bridge bridgeToExtend = stepToExtend.Bridge; if (closeSet.Contains(bridgeToExtend)) { continue; } closeSet.Add(bridgeToExtend); // when reach a bridge with an end connected to the goal (check in the dictionary allLastParts) for the first time, mark it as one possible solution // with the mark, add also the weight of the last part which connect the end bridge and the goal // then, re-insert it in the open list at the right index. // if we try to extend a bridge already marked, then it's the shortest solution // if the bridge to extend is a bridge with the end connected to the goal cluster (in dictionary allLastParts) if (endCluster.Bridges.Exists(bridge => bridge.Start == bridgeToExtend.End) && allLastParts.ContainsKey(bridgeToExtend.End)) { // mark step as possible solution and add the weight of the right last part stepToExtend.MarkAsSolution(allLastParts[stepToExtend.Bridge.End].Weight); // find the right index to re-insert in open list // if we try to extend it again, it means that it's the shortest path to the goal int indexInsertion = openList.BinarySearch(stepToExtend, comparer); if (indexInsertion < 0) { indexInsertion = ~indexInsertion; } openList.Insert(indexInsertion, stepToExtend); } else { // Get the cluster from the bridgeToExtend End Cluster cluster = _GridClustered.GetClusterOfTile(bridgeToExtend.End); // Get the right reversed bridge Bridge reverseBridge = cluster.Bridges.Find(b => b.Start == bridgeToExtend.End); // loop through all the reversed bridge neighbors foreachNeighborsChrono -= chrono.ElapsedMilliseconds; foreach (Bridge neighbor in reverseBridge.Neighbors.Keys) { // if the bridge is already in close set, skip to next neighbor searchInCloseListChrono -= chrono.ElapsedMilliseconds; bool existInCloseList = closeSet.Contains(neighbor); searchInCloseListChrono += chrono.ElapsedMilliseconds; if (existInCloseList) { continue; } // create extension with neighbor extendPathChrono -= chrono.ElapsedMilliseconds; BridgeStep extension = stepToExtend.MakeExtensionWith(neighbor, reverseBridge.Neighbors[neighbor].Weight); extendPathChrono += chrono.ElapsedMilliseconds; searchInsertionChrono -= chrono.ElapsedMilliseconds; int indexInsertion = openList.BinarySearch(extension, comparer); if (indexInsertion < 0) { indexInsertion = ~indexInsertion; } searchInsertionChrono += chrono.ElapsedMilliseconds; insertToOpenListChrono -= chrono.ElapsedMilliseconds; openList.Insert(indexInsertion, extension); insertToOpenListChrono += chrono.ElapsedMilliseconds; } foreachNeighborsChrono += chrono.ElapsedMilliseconds; } } // No path found in limited time _ChronoInfos = StopChrono(_Start, _End, false); return(null); }