private void CreateConnections() { for (int y = 0; y < tileCount; y++) { for (int x = 0; x < tileCount; x++) { bool activeConnection = Random.Range(0.0f, 1.0f) > removeRoadChance || x == 0 || x == tileCount - 1 || y == 0 || y == tileCount - 1; if (x != 0) { RoadNode.CreateConnection(RoadNodes[x, y], RoadNodes[x - 1, y], Direction.Left, activeConnection); } if (x != tileCount - 1) { RoadNode.CreateConnection(RoadNodes[x, y], RoadNodes[x + 1, y], Direction.Right, activeConnection); } if (y != 0) { RoadNode.CreateConnection(RoadNodes[x, y], RoadNodes[x, y - 1], Direction.Down, activeConnection); } if (y != tileCount - 1) { RoadNode.CreateConnection(RoadNodes[x, y], RoadNodes[x, y + 1], Direction.Up, activeConnection); } } } }
// Administra los checkpoints void CrossCheckPoint(Collider other) { resetTransform.position = other.transform.position; resetTransform.rotation = other.transform.rotation; nodeCrossedParams = other.transform.parent.parent.GetComponent <RoadNode>(); if (nodeCrossedParams == null) { print("[ERROR] RoadNode not found on road parent."); return; } nodeCrossedParams.CrossCheckPoint(); // En el caso de que el jugador de alguna forma se salte parte de la carretera, esto comprueba cuantos nodos se ha saltado. for (int i = 0; i < nodeCrossedParams.GetID() - lastNodeCrossedID; i++) { RoadGenerator.currentInstance.SpawnNextNode(); StageData.currentData.nodesCrossed++; } lastNodeCrossedID = nodeCrossedParams.GetID(); // RETURN si no se trata de un punto de control marcado como activo. if (other.tag == "CP_Active") { StageData.currentData.PlayerCrossedCheckPoint(cleanSection, nodeCrossedParams.GetTimeAwarded()); StageData.currentData.PlayerCrossedNode(); cleanSection = true; } else { StageData.currentData.PlayerCrossedNode(); } }
public UrbanPlanningOffice(City givenCity, RoadBuilder roadB = null, StructureBuilder structureB = null) : base(givenCity) { roader = (roadB == null) ? new RoadBuilder(city) : roadB; structurer = (structureB == null) ? new StructureBuilder(city) : structureB; roadSpaceAvailable = city.startRoad != null && city.startRoad.HasRoad() && city.startRoad.Neighbors().FindIndex(elem => elem.IsBuildable()) >= 0; buildingSpaceAvailable = roadSpaceAvailable; expandableRoads = new List <RoadNode>(); List <Direction> must = new List <Direction>(); must.Add(Direction.East); must.Add(Direction.West); List <Direction> can = new List <Direction>(); int[] depths = new int[4] { -1, -1, -1, -1 }; RoadNode firstNode = new RoadNode((Road)city.startRoad.Surface, must, can, depths); if (firstNode.IsAvailable()) { expandableRoads.Add(firstNode); } }
public AStarHelper(Transform destiny, RoadCreator creator) { this.creator = creator; destination = destiny; ArrayList original = new ArrayList(); if(creator.lastIdx == 0){ RoadNode rn0 = new RoadNode(0, creator.lastChunk, creator.lastRotY, 0, creator, original, destination); rn0.mountPoint.name = "Astar-0"; open.Add(rn0, rn0); RoadNode rn1 = new RoadNode(1, creator.lastChunk, creator.lastRotY, 0, creator, original, destination); rn1.mountPoint.name = "Astar-1"; open.Add(rn1, rn1); RoadNode rn2 = new RoadNode(2, creator.lastChunk, creator.lastRotY, 0, creator, original, destination); rn2.mountPoint.name = "Astar-2"; open.Add(rn2, rn2); expanded=3; } else { RoadNode rn0 = new RoadNode(0, creator.lastChunk, creator.lastRotY, 0, creator, original, destination); rn0.mountPoint.name = "Astar-0"; open.Add(rn0, rn0); expanded=1; } }
protected Stack <Node> FindPath(RoadNode from, RoadNode to) { Node nodeFrom = from.Node; Node nodeTo = to.Node; return(mainAi.MaphGraph.GetMinPathFromTo(nodeFrom, nodeTo)); }
public void Connect(RoadNode a, RoadNode b) { Vector2 deltaPos = a.transform.position - b.transform.position; deltaPos = new Vector2(Mathf.RoundToInt(deltaPos.x), Mathf.RoundToInt(deltaPos.y)); if (!Mathf.Approximately(deltaPos.magnitude, 1)) { return; } if (deltaPos == Vector2.up) { a.ConnectWith(b, Direction.South); b.ConnectWith(a, Direction.North); } else if (deltaPos == Vector2.down) { a.ConnectWith(b, Direction.North); b.ConnectWith(a, Direction.South); } else if (deltaPos == Vector2.left) { a.ConnectWith(b, Direction.East); b.ConnectWith(a, Direction.West); } else if (deltaPos == Vector2.right) { a.ConnectWith(b, Direction.West); b.ConnectWith(a, Direction.East); } }
private NodeGenerationInfo GenerateNodeInfo(RoadNode checkedRoadNode, int index) { if (nodesMap.ContainsKey(checkedRoadNode)) { return(null); } var nodeInfo = new NodeGenerationInfo(); nodeInfo.position = checkedRoadNode.transform.position; nodesMap.Add(checkedRoadNode, nodeInfo); nodesList.Add(nodeInfo); nodeInfo.nodesAtSamePosition.Add(checkedRoadNode); for (int i = index + 1; i < roadPieces.Length; i++) { var roadPiece = roadPieces[i]; foreach (var roadNode in roadPiece.RoadNodes) { if (Vector3.Distance(checkedRoadNode.transform.position, roadNode.transform.position) < MINIMUM_PROXIMITY) { nodesMap.Add(roadNode, nodeInfo); nodeInfo.nodesAtSamePosition.Add(roadNode); } } } return(nodeInfo); }
public int CompareTo(object other) { RoadNode otherRoad = other as RoadNode; if (otherRoad != null) { if (this.heuristicCost(destination) > otherRoad.heuristicCost(destination)) { return(1); } if (this.heuristicCost(destination) < otherRoad.heuristicCost(destination)) { return(-1); } else { if (this.mountPoint.name.Equals(otherRoad.mountPoint.name)) { return(0); } else { return(-1); // quiero que me los diferencie sí o sí, por eso -1 en lugar de 0. } } } else { throw new ArgumentException("The object is no RoadNode"); } }
private void Clear(RoadGraphDatabase roadGraphDB) { roadGraphDB.Clear(); fromNode = null; toNode = null; EditorUtility.SetDirty(roadGraphDB); }
//GUI interface public void AddConnection(RoadNode fromNode, RoadNode toNode, float cost, bool directed) { Assert.IsNotNull(fromNode); Assert.IsNotNull(toNode); if (roadGraph == null) { roadGraph = new Graph <RoadNode>(); Debug.Log("New Graph"); } //if (roadGraph.ContainsValue(fromNode) && roadGraph.ContainsValue(toNode)) //{ // return; //} if (directed) { roadGraph.AddAndConnectDirected(fromNode, toNode, cost); } else { roadGraph.AddAndConnect(fromNode, toNode, cost); } Save(); }
public void OnPointToAvailableNode(RoadNode node, bool isForward) { Destroy(blueprint); state = State.Pointing; nodeType = GetNodeTypeByColliderDirection(isForward); GenerateShortestRoadBlueprint(node, isForward); }
public AStarHelper(Transform destiny, RoadCreator creator) { this.creator = creator; destination = destiny; ArrayList original = new ArrayList(); if (creator.lastIdx == 0) { RoadNode rn0 = new RoadNode(0, creator.lastChunk, creator.lastRotY, 0, creator, original, destination); rn0.mountPoint.name = "Astar-0"; open.Add(rn0, rn0); RoadNode rn1 = new RoadNode(1, creator.lastChunk, creator.lastRotY, 0, creator, original, destination); rn1.mountPoint.name = "Astar-1"; open.Add(rn1, rn1); RoadNode rn2 = new RoadNode(2, creator.lastChunk, creator.lastRotY, 0, creator, original, destination); rn2.mountPoint.name = "Astar-2"; open.Add(rn2, rn2); expanded = 3; } else { RoadNode rn0 = new RoadNode(0, creator.lastChunk, creator.lastRotY, 0, creator, original, destination); rn0.mountPoint.name = "Astar-0"; open.Add(rn0, rn0); expanded = 1; } }
public List <RoadNode> GetPath(RoadNode nodeFrom, RoadNode nodeTo) { target = nodeTo; openNodes = new SortedList <float, RoadNode>(); closedNodes = new HashSet <RoadNode>(); distanceFromStart = new Dictionary <RoadNode, float>(); predecessors = new Dictionary <RoadNode, RoadNode>(); openNodes.Add(0, nodeFrom); while (openNodes.Count != 0) { var currentNode = openNodes[0]; openNodes.RemoveAt(0); if (currentNode == nodeTo) { return(ReconstructPath()); } closedNodes.Add(currentNode); ExpandNode(currentNode); } throw new Exception("No path found"); }
public RouteNode(RoadNode node, int weight) { Blacklist = new List <RoadNode>(); Name = node.name; Weight = weight; Value = node; }
public static void CreateConnection(RoadNode from, RoadNode to, Direction direction, bool activeConnection) { switch (direction) { case Direction.Up: from.Up_connection = new RoadNodeConnection(to, activeConnection); to.Down_connection = new RoadNodeConnection(from, activeConnection); break; case Direction.Down: from.Down_connection = new RoadNodeConnection(to, activeConnection); to.Up_connection = new RoadNodeConnection(from, activeConnection); break; case Direction.Left: from.Left_connection = new RoadNodeConnection(to, activeConnection); to.Right_connection = new RoadNodeConnection(from, activeConnection); break; case Direction.Right: from.Right_connection = new RoadNodeConnection(to, activeConnection); to.Left_connection = new RoadNodeConnection(from, activeConnection); break; } }
private IEnumerator MoveToCoroutine(RoadNode node) { Vector3 position = transform.position; Vector3 target = node.transform.position; Vector3 direction = target - position; transform.rotation = Quaternion.LookRotation(direction, Vector3.up); float distance = Vector3.Distance(position, target); float t = 0; while (t < 1) { if (!Physics.Raycast(new Ray(transform.position, transform.forward), out RaycastHit _, raycastDistance, carLayerMask)) { t += Time.deltaTime * speed / distance; transform.position = Vector3.Lerp(position, target, t); } yield return(null); } isMoving = false; if (nextNode) { MoveTo(nextNode); } }
private void ExpandNode(RoadNode node) { foreach (var successor in GetSuccessors(node)) { if (closedNodes.Contains(successor)) { continue; } float oldDistance; distanceFromStart.TryGetValue(node, out oldDistance); float newDistance; distanceFromStart.TryGetValue(successor, out newDistance); newDistance += 1; if (openNodes.ContainsValue(successor) && newDistance >= oldDistance) { continue; } predecessors[successor] = node; distanceFromStart[successor] = newDistance; if (openNodes.ContainsValue(successor)) { openNodes.RemoveAt(openNodes.IndexOfValue(successor)); } var cost = newDistance + CalculateLinearDistance(successor, target); openNodes.Add(cost, successor); } }
public RoadEdge(RoadNode from, RoadNode to, Waypoint[] waypoints) { this.from = from; this.to = to; this.waypoints = waypoints; this.weight = GetWeight(waypoints.Length); }
public void QueueMoveTo(RoadNode next) { nextNode = next; if (!isMoving) { MoveTo(next); } }
private static IEnumerable <RoadNode> GetSuccessors(RoadNode node) { return(node.Connections.Select(c => c.NodeA = node ? c.NodeB : c.NodeA) .ToList()); }
public void ConnectWith(RoadNode node, Direction dir) { connections[dir] = new RoadConnection() { from = this, to = node }; }
public void AddConnection(RoadNode aNode) { if (mConnections.Contains(aNode) == false && aNode.mConnections.Contains(this) == false) { mConnections.Add(aNode); aNode.mConnections.Add(this); } }
public IEnumerator Coroutine_GenerateParcels(List <RoadNode> aNodes) { mNodesForParcels = aNodes.ToList(); bool donedone = false; while (donedone == false) { ClearFilaments(ref mNodesForParcels); yield return(new WaitForSeconds(1)); if (mNodesForParcels.Count <= 2) { donedone = true; break; } mCurrentParcel.Clear(); List <RoadNode> nodes = mNodesForParcels.OrderBy(i => i.mPosition.x).ToList(); RoadNode startNode = nodes[0]; RoadNode currentNode = startNode; Vector3 currentDirection = Vector3.forward; currentNode.mIsPath = true; RoadNode previousNode = currentNode; bool done = false; while (done == false) { currentNode.mConnections = currentNode.mConnections.OrderBy(i => Angle(currentNode.mPosition, i.mPosition, currentDirection)).ToList(); if (currentNode == startNode) { currentNode.mConnections.Reverse(); } RoadNode nextNode = currentNode.mConnections[0]; for (int i = 0; i < currentNode.mConnections.Count; ++i) { if (currentNode.mConnections[i] == previousNode) { continue; } nextNode = currentNode.mConnections[i]; } currentDirection = (currentNode.mPosition - nextNode.mPosition).normalized; previousNode = currentNode; currentNode = nextNode; currentNode.mIsPath = true; mCurrentParcel.Add(currentNode); if (currentNode == startNode) { done = true; } //yield return new WaitForSeconds(1); } FixParcel(); mCurrentParcel.Last().mConnections.Remove(mCurrentParcel.First()); mCurrentParcel.First().mConnections.Remove(mCurrentParcel.Last()); yield return(new WaitForSeconds(1)); } yield return(new WaitForSeconds(1)); }
public void StopMoving() { isMoving = false; nextNode = null; if (moveCoroutine != null) { StopCoroutine(moveCoroutine); moveCoroutine = null; } }
public void setFrontRoad(RoadNode node) { if (m_FrontRoad == null) { m_FrontRoad = node; } else { Debug.LogAssertion("重复绑定FrontRoad!!"); } }
public static RoadNode ResolveRoadNodePosition(Vector3 origin, float heading) { RoadNode outNode; //check segment crossing //check node proximity //otherwise outNode = new RoadNode(); outNode.position = origin + Quaternion.AngleAxis(heading, Vector3.up) * (roadNodeStep * Vector3.forward); return(outNode); }
private void ProcessWall(int i, Transform transform, Node node, RoadNode roadNode) { mainAi.CurNode.IsNotWall(i); roadNode.IsNotWall((i + 2) % 4); Verticie vert = new Verticie(); vert.first = node; vert.second = mainAi.CurNode.Node; mainAi.MaphGraph.nodes.Add(node); mainAi.MaphGraph.verticies.Add(vert); }
public bool Contains(RoadNode node) { foreach (var routeNode in this) { if (routeNode.Value == node) { return(true); } } return(false); }
protected void setBackRoad(RoadNode node) { if (m_BehideRoad == null) { m_BehideRoad = node; } else { Debug.LogAssertion("重复绑定BackRoad!!"); } }
private void MoveTo(RoadNode node) { if (isMoving) { return; } isMoving = true; nextNode = null; moveCoroutine = StartCoroutine(MoveToCoroutine(node)); }
//Run time queries public IEnumerable <RoadNode> FindPath(RoadNode startNode, RoadNode endNode) { Assert.IsTrue(roadGraph.ContainsValue(startNode)); Assert.IsTrue(roadGraph.ContainsValue(endNode)); GraphNode <RoadNode> startGraphNode = roadGraph.GetNodeByValue(startNode); GraphNode <RoadNode> endGraphNode = roadGraph.GetNodeByValue(endNode); List <GraphNode <RoadNode> > graphNodePath = astarCalc.CalculatePath(startGraphNode, endGraphNode); Assert.IsTrue(graphNodePath.Count > 0); return(graphNodePath.Select(graphNode => graphNode.Value)); }
public RoadNode[] children() { RoadNode[] toReturn; if(chunkIdx != 0){ toReturn = new RoadNode[1]; toReturn[0] = new RoadNode(0, mountPoint, rotY, costSoFar, creator, pathUntilNow, destination); } else { toReturn = new RoadNode[3]; toReturn[0] = new RoadNode(0, mountPoint, rotY, costSoFar, creator, pathUntilNow, destination); toReturn[1] = new RoadNode(1, mountPoint, rotY, costSoFar, creator, pathUntilNow, destination); toReturn[2] = new RoadNode(2, mountPoint, rotY, costSoFar, creator, pathUntilNow, destination); } return toReturn; }
public static MapEntry Read(FileEntry entry, BinaryReader br) { var t = new MapEntry { MapVersion = br.ReadUInt32(), MapFileName = entry.Name }; // 60 < MapVersion < 62 #region Header if (t.MapVersion < 4 || t.MapVersion > 62) return null; if (t.MapVersion >= 27) t.IterationVersion = br.ReadUInt32(); br.ReadBytes(8); t.GridSize = br.ReadSingle(); t.TileSet = br.ReadByte(); t.UseRoad = br.ReadBoolean(); t.Music = br.Read<UInt16>(3); if (t.MapVersion >= 11) { t.UseClouds = br.ReadBoolean(); t.UseTimeOfDay = br.ReadBoolean(); t.FileName = br.ReadLengthedString(); } if (t.MapVersion >= 36) t.CullingStyle = br.ReadSingle(); if (t.MapVersion >= 45) t.NumOfImports = br.ReadUInt32(); #endregion #region Common Data t.EntryX = br.ReadSingle(); t.EntryY = br.ReadSingle(); t.EntryZ = br.ReadSingle(); t.EntryW = br.ReadSingle(); t.NumModulePlacements = br.ReadInt32(); t.NumOfVOGOs = br.ReadInt32(); t.NumOfClientVOGOs = br.ReadInt32(); t.HighestCoid = br.ReadUInt32(); t.PerPlayerLoadTrigger = br.ReadInt64(); t.CreatorLoadTrigger = br.ReadInt64(); if (t.MapVersion >= 33) t.OnKillTrigger = br.ReadInt64(); if (t.MapVersion >= 34) t.LastTeamTrigger = br.ReadInt64(); var missC = br.ReadUInt32(); for (var i = 0U; i < missC; ++i) { var ms = MissionString.Read(br, t.MapVersion); t.MissionStrings.Add(ms.StringId, ms); } var wpC = br.ReadUInt32(); for (var i = 0U; i < wpC; ++i) { var wp = VisualWaypoint.Read(br, t.MapVersion); t.VisualWaypoints.Add(wp.Id, wp); } var varC = br.ReadUInt32(); for (var i = 0U; i < varC; ++i) { var v = Variable.Read(br, t.MapVersion); t.Variables.Add(v.Id, v); } if (t.MapVersion >= 47) { t.WeatherStrEffect = br.ReadLengthedString(); var regionCount = br.ReadUInt32(); for (var i = 0U; i < regionCount; ++i) { var regionId = br.ReadByte(); if (!t.WeatherInfos.ContainsKey(regionId)) t.WeatherInfos.Add(regionId, new WeatherContainer()); var weatherCount = br.ReadUInt32(); for (var j = 0U; j < weatherCount; ++j) { t.WeatherInfos[regionId].Weathers.Add(new WeatherInfo { SpecialType = br.ReadUInt32(), Type = br.ReadUInt32(), PercentChance = br.ReadSingle(), SpecialEventSkill = br.ReadInt32(), EventTimesPerMinute = br.ReadByte(), MinTimeToLive = br.ReadUInt32(), MaxTimeToLive = br.ReadUInt32(), LayerBits = t.MapVersion >= 54 ? br.ReadUInt32() : 1, FxName = br.ReadLengthedString() }); } t.WeatherInfos[regionId].Effect = br.ReadLengthedString(); for (var j = 0; j < 4; ++j) t.WeatherInfos[regionId].Environments.Add(br.ReadLengthedString()); } } if (t.MapVersion >= 38) { // Sea Plane Data if (t.MapVersion >= 35) { if (br.ReadByte() != 0) { var planeCount = br.ReadInt32(); t.SeaPlane.Coords = Vector4.Read(br); t.SeaPlane.CoordsList = new List<Vector4>(planeCount); for (var i = 0; i < planeCount; ++i) t.SeaPlane.CoordsList.Add(Vector4.Read(br)); } } } #endregion Debug.Assert(t.NumModulePlacements == 0, "WTF Happened?!"); #region VOGOs for (var i = 0; i < t.NumOfClientVOGOs + t.NumOfVOGOs; ++i) { Byte layer = 0; if (t.MapVersion > 5) layer = br.ReadByte(); var cbid = br.ReadInt32(); var coid = br.ReadInt32(); var skipBytes = br.ReadInt32(); // skip this many bytes, if client already loaded this clone base object var obj = ClonedObjectBase.AllocateNewObjectFromCBID(cbid); if (obj == null) { br.BaseStream.Seek(skipBytes, SeekOrigin.Current); continue; } obj.InitializeFromCBID(cbid, null); obj.Layer = layer; obj.SetCOID(coid); var pos = br.BaseStream.Position; try { obj.Unserialize(br, t.MapVersion); } catch (EndOfStreamException) { Console.WriteLine("EOS?!?!"); } if (!t.ObjectBasesByType.ContainsKey(obj.Type)) t.ObjectBasesByType.Add(obj.Type, new List<ClonedObjectBase>()); t.ObjectBasesByType[obj.Type].Add(obj); if (pos + skipBytes == br.BaseStream.Position) continue; Console.WriteLine("COID: {0} ({1}) | {2} reading | Read size: {3} | Total size: {4} | Diff: {5}", coid, obj.Type, (pos + skipBytes > br.BaseStream.Position ? "under" : "over"), Math.Abs(br.BaseStream.Position - pos), skipBytes, skipBytes - Math.Abs(br.BaseStream.Position - pos)); br.BaseStream.Position = pos + skipBytes; } #endregion #region Roads if (t.MapVersion >= 43) t.Flags = br.ReadUInt32(); var numRoads = br.ReadUInt32(); for (var i = 0U; i < numRoads; ++i) { /*var unk = */ br.ReadUInt32(); var type = br.ReadByte(); RoadNodeBase roadNodeBase; switch (type) { case 0: roadNodeBase = new RoadNode(); break; case 1: roadNodeBase = new RoadJunction(); break; case 2: roadNodeBase = new RiverNode(); break; default: throw new InvalidDataException("Invalid road node base type!"); } roadNodeBase.UnSerialize(br, t.MapVersion); t.Roads.Add(roadNodeBase); } #endregion #region Music if (t.MapVersion >= 42) { var numMusicRegion = br.ReadUInt32(); for (var i = 0U; i < numMusicRegion; ++i) { /*var unk = */ br.ReadUInt32(); if (t.MapVersion < 42) continue; /*var musicName = */ br.ReadLengthedString(); /*var looping = */ br.ReadBoolean(); /*var silenceatmaxradius = */ br.ReadBoolean(); /*var durationForRepeat = */ br.ReadSingle(); /*var fadeintime = */ br.ReadSingle(); /*var fadeouttime = */ br.ReadSingle(); /*var maxradius = */ br.ReadSingle(); /*var x = */ br.ReadSingle(); /*var y = */ br.ReadSingle(); /*var z = */ br.ReadSingle(); /*var musicType = */ br.ReadUInt32(); } } #endregion #region MapFlair if (t.MapVersion >= 30) { /*var streamVer = */ br.ReadUInt32(); /*var width = */ br.ReadInt32(); /*var height = */ br.ReadInt32(); /*var maxobjcountperglomsector = */ br.ReadInt32(); var objectcount = br.ReadInt32(); for (var i = 0; i < objectcount; ++i) { /*var streamVer2 = */ br.ReadUInt32(); /*var cbidVisual = */ br.ReadInt32(); /*var drawSizeMin = */ br.ReadSingle(); /*var drawSizeVariance = */ br.ReadSingle(); /*var thresholdMin = */ br.ReadByte(); /*var thresholdMax = */ br.ReadByte(); /*var layerMask = */ br.ReadByte(); /*var placeWithGroundNormal = */ br.ReadByte(); } var inlineDensityMap = br.ReadBoolean(); Debug.Assert(!inlineDensityMap, "I HOPE THIS IS UNREACHABLE!"); } #endregion var stream = AssetManager.GetStreamByName(entry.Name.ToLower().Replace(".fam", ".xml")); if (stream != null) { using (stream) { var doc = XDocument.Load(stream); Debug.Assert(doc != null); var element = doc.Element("Map"); if (element != null) { t.ContinentId = (UInt32)element.Attribute("continentObjectID"); t.Name = (String)element.Element("Name"); t.Description = (String)element.Element("Description"); } } } else { Debug.Assert(false, "Nincs a mapnak info-ja ?!?!?!"); } return t; }
bool isEnd(RoadNode node) { return Vector3.Distance(node.mountPoint.position,destination.position) < 6 && Quaternion.Angle(node.mountPoint.rotation,destination.rotation) < 1; }