private void IndentityMonoAdd() { /* * Set up a unique value for each Road and Connection. * This is because we cannot use the Road or Connection name in ECS as strings are not allowed (only bittable data can be used) * AND because road and connection names may not be unique. * We need the unique value to identify the relationship between road and connection */ ERRoadNetwork roadNetwork = new ERRoadNetwork(); ERRoad[] roads = roadNetwork.GetRoads(); ERConnection[] connections = roadNetwork.GetConnections(); int identity = 0; foreach (ERRoad road in roads) { road.gameObject.AddComponent <ERRoadConnectionIdentity>(); road.gameObject.GetComponent <ERRoadConnectionIdentity>().value = identity; identity++; } foreach (ERConnection connection in connections) { connection.gameObject.AddComponent <ERRoadConnectionIdentity>(); connection.gameObject.GetComponent <ERRoadConnectionIdentity>().value = identity; identity++; } }
private void BuildAllRoute() { markers = roadNetwork.GetRoads(); for (int i = 0; i < markers.Length; i++) { Debug.Log(i + " GetMarkerPositions = " + markers[i].GetMarkerPositions()); Debug.Log(i + " GetSplinePointsCenter = " + markers[i].GetSplinePointsCenter()); } }
private const byte buildingSizeMultiplier = 3; //CScape uses a 1 to 3 setting for their buildings, so this is to deal with that. public void PlaceBuildings() { try { if (buildingTag.Trim().Length == 0 || roadTag.Trim().Length == 0) { Debug.Log("You must have building and road tags set"); return; } //To insure the percentage is never over 100 if (percentBuildingBack > 100) { percentBuildingBack = 100; } //Use only tagged roads and buildings, that way if you have sections the way you want them, this code will not affect the untagged assets buildings = GameObject.FindGameObjectsWithTag(buildingTag).ToList(); List <GameObject> roads = GameObject.FindGameObjectsWithTag(roadTag).ToList(); ERRoadNetwork roadNetwork = new ERRoadNetwork(); ERRoad[] ERroads = roadNetwork.GetRoads(); string roadName = ""; //Move the buildings out of the way foreach (GameObject building in buildings) { building.transform.position = new Vector3(-100, 0, -100); } foreach (ERRoad road in ERroads) { roadName = road.GetName(); //Make sure the road is in the tagged list if (RoadInList(roads, roadName)) { Vector3[] markersRight = road.GetSplinePointsRightSide(); Vector3[] markersLeft = road.GetSplinePointsLeftSide(); Vector3[] markersCenter = road.GetSplinePointsCenter(); Vector3[] markersOffset = markersCenter; PlaceBuildings(markersRight, markersCenter, true, road); PlaceBuildings(markersLeft, markersCenter, false, road); } } } catch (System.Exception ex) { Debug.Log("Place Building Ex: " + ex.Message); } }
private void IdentityMonoRemove() { ERRoadNetwork roadNetwork = new ERRoadNetwork(); ERRoad[] roads = roadNetwork.GetRoads(); ERConnection[] connections = roadNetwork.GetConnections(); foreach (ERRoad road in roads) { Destroy(road.gameObject.GetComponent <ERRoadConnectionIdentity>()); } foreach (ERConnection connection in connections) { Destroy(connection.gameObject.GetComponent <ERRoadConnectionIdentity>()); } }
/// <summary> /// Methode zum Platzieren des Autos am Anfang. /// </summary> private void PlaceCameraCar() { // Das Auto auf die rechte erste Spur platzieren ERRoad firstRoad = network.GetRoads().First(); Vector3 firstSplineRightSide = firstRoad.GetSplinePointsRightSide()[0]; Vector3 firstMarker = firstRoad.GetMarkerPosition(0); Vector3 rightMiddleLane = Vector3.zero; // Das Position je nach Anzahl der Spuren interpolieren switch (this.numberOfTracks) { case 8: rightMiddleLane = Vector3.Slerp(firstMarker, firstSplineRightSide, 0.85f); break; case 6: rightMiddleLane = Vector3.Slerp(firstMarker, firstSplineRightSide, 0.825f); break; case 4: rightMiddleLane = Vector3.Slerp(firstMarker, firstSplineRightSide, 0.75f); break; case 2: default: rightMiddleLane = Vector3.Slerp(firstMarker, firstSplineRightSide, 0.5f); break; } // Das Auto an die richtige Positions etzen cameraCar.gameObject.transform.position = rightMiddleLane; cameraCar.gameObject.transform.rotation = Quaternion.identity; // Ist platziert setzen isPlaced = true; }
/// <summary> /// Methode zum Zeichnen einer geraden Straße. /// </summary> /// <param name="length">Die Länge der Straße.</param> /// <param name="minCars">Die minimale Anzahl der Autos auf dem Straßenteil.</param> /// <param name="maxCars">Die maximale Anzahl der Autos auf dem Straßenteil.</param> /// <param name="heightDifference">Der Höhenunterschied.</param> /// <param name="seed">Der Seed.</param> /// <returns>Die Straße.</returns> public ERRoad CreateStraight(float length, int minCars, int maxCars, float?heightDifference, string seed) { // Die Strecke neu holen this.network = new ERRoadNetwork(); this.network.BuildRoadNetwork(); // Den RoadType holen ERRoadType roadType = this.GetRandomRoadType(); // Hole die akutellen Streckenteile ERRoad[] currentRoads = network.GetRoads(); // Hole die Höhe der Strecke float fixHeightDifference = heightDifference ?? 0; // Lege die Positionen der Strecke an Vector3 startPosition = new Vector3(0, 0, 0); Vector3 middlePosition = new Vector3(0, fixHeightDifference / 2, length / 2); Vector3 endPosition = new Vector3(0, fixHeightDifference, length); ERRoad lastRoad = null; ERRoad road = null; if (currentRoads.Length > 0) { // Hole die letzte Strecke lastRoad = currentRoads.Last(); // Hole den letzten Punkt der Strecke Vector3[] markers = lastRoad.GetMarkerPositions(); Vector3 lastMarker = markers.Last(); // Die richtige Rotation ausrechnen Vector3 heading = (lastMarker - markers[markers.Length - 2]); Vector3 direction = heading / heading.magnitude; direction.y = 0; // Das Verhältnis zwischen x und z-Achse ausrechnen float x = direction.x / (direction.magnitude); float z = direction.z / (direction.magnitude); Vector3[] streetVectors = new Vector3[(int)length]; float heightPart = fixHeightDifference / length; for (int lengthPart = 0; lengthPart < length; lengthPart++) { streetVectors[lengthPart] = lastMarker + new Vector3(x * lengthPart, heightPart * lengthPart, z * lengthPart); } // Generiere Straße road = network.CreateRoad("Straight" + currentRoads.Length, roadType, streetVectors); } else { // Generiere erste Straße road = network.CreateRoad("Straight" + currentRoads.Length, roadType, new Vector3[] { startPosition, middlePosition, endPosition }); } // Erstelle die Strecke mit einem eindeutigen Namen customEasyRoads.Add(new CustomEasyRoad(car, road, minCars, maxCars, numberOfTracks)); return(road); }
/// <summary> /// Erstellt eine Kurve anhand eines Winkels, der Länge der Kurve und den Positionen des aktuellen und vorherigen Straßen Elementes. /// </summary> /// <param name="angle">Der Winkel.</param> /// <param name="length">Die Länge des Straßenelementes.</param> /// <param name="heightDifference">Die Höhendifferenz für den Streckenabschnitt.</param> /// <param name="minCars">Die minimale Anzahl an Autos auf diesem Streckenabschnitt.</param> /// <param name="maxCars">Die maximale Anzahl an Autos auf diesem Streckenabschnitt.</param> /// <param name="seed">Der Seed des Random-Generators.</param> /// <returns>Die Kurve.</returns> public ERRoad CreateCurve(float angle, float length, float?heightDifference, int minCars, int maxCars, string seed) { // Die Strecke neu holen this.network = new ERRoadNetwork(); this.network.BuildRoadNetwork(); // hole die Höhendifference float fixHeightDifference = heightDifference ?? 0f; // Die StartPosition initialisieren. Vector3 startPosition = new Vector3(0, 0, 0); // Die Ausrichtung initialisieren (default ist z-Richtung). Vector3 heading = new Vector3(0, 0, 1); // Den RoadType holen ERRoadType roadType = this.GetRandomRoadType(); // Hole die Position des letzten Streckenabschnitts, wenn vorhanden. ERRoad lastRoad = null; if (network.GetRoads().Length > 0) { lastRoad = network.GetRoads().Last(); Vector3[] markers = lastRoad.GetMarkerPositions(); Vector3 lastPosition = markers.Last(); // Die Startposition an den letzten Streckenabschnitt anpassen. startPosition = lastPosition; // Die Ausrichtung in Bezug auf den vorherigen Streckenabschnitt holen. Vector3 secondToLast = markers[markers.Count() - 2]; heading = lastPosition - secondToLast; heading.y = 0; } // Den (geraden) Richtungsvektor berechnen. Vector3 direction = heading / heading.magnitude; // Der Vektor der y-Achse Vector3 yAxis = new Vector3(0, 1, 0); // Die Anzahl an zu berechnenden Positionen für die Kurve int numbPositions = Convert.ToInt32(Math.Abs(angle)); float positionPercentage = numbPositions * percentageEven; // Das Array mit den neuen Positionen. Vector3[] curvePositions = new Vector3[numbPositions]; curvePositions[0] = startPosition; // es werden in 1-Grad-Schritten Positionen berechnet. float anglePart = angle / Math.Abs(angle); float lengthPart = length / numbPositions; float heightPart = fixHeightDifference / (numbPositions - (2 * positionPercentage)); // Die Positionen berechnen. for (int i = 1; i < numbPositions; i++) { // Die direction für den nächsten Schritt berechnen if (i > 1) { heading = curvePositions[i - 1] - curvePositions[i - 2]; heading.y = 0; direction = heading / heading.magnitude; } // Die letzte Position holen. Vector3 oldPosition = curvePositions[i - 1]; // innerhalb des Prozent-Bereiches die Höhe anwenden. if (i > positionPercentage && i < (numbPositions - positionPercentage)) { oldPosition.y += heightPart.Truncate(5); } // Die neue Position berechnen. curvePositions[i] = oldPosition + Quaternion.AngleAxis(anglePart, yAxis) * direction * lengthPart; } // Die Kurve erzeugen. ERRoad thisRoad = this.network.CreateRoad("Curve" + network.GetRoads().Count(), roadType, curvePositions); customEasyRoads.Add(new CustomEasyRoad(car, thisRoad, minCars, maxCars, numberOfTracks)); return(thisRoad); }
public override void OnInspectorGUI() { _easyRoadNodes = (EasyRoadNodes)target; ERRoadNetwork network = new ERRoadNetwork(); _easyRoadNodes.ERRoads = network.GetRoads().ToList(); if (_easyRoadNodes.DontBuild.Count == 0) { for (int i = 0; i < _easyRoadNodes.ERRoads.Count; i++) { _easyRoadNodes.DontBuild.Add(false); } } if (_easyRoadNodes.Inverted.Count == 0) { for (int i = 0; i < _easyRoadNodes.ERRoads.Count; i++) { _easyRoadNodes.Inverted.Add(false); } } if (_easyRoadNodes.LinesCount.Count == 0) { for (int i = 0; i < _easyRoadNodes.ERRoads.Count; i++) { _easyRoadNodes.LinesCount.Add(2); } } if (_easyRoadNodes.DontBuild.Count != _easyRoadNodes.ERRoads.Count) { bool[] bools = new bool[_easyRoadNodes.DontBuild.Count]; _easyRoadNodes.DontBuild.CopyTo(bools); _easyRoadNodes.DontBuild.Clear(); for (int i = 0; i < _easyRoadNodes.ERRoads.Count; i++) { if (bools.Length > i) { _easyRoadNodes.DontBuild.Add(bools[i]); } else { _easyRoadNodes.DontBuild.Add(false); } } } if (_easyRoadNodes.Inverted.Count != _easyRoadNodes.ERRoads.Count) { bool[] bools = new bool[_easyRoadNodes.Inverted.Count]; _easyRoadNodes.Inverted.CopyTo(bools); _easyRoadNodes.Inverted.Clear(); for (int i = 0; i < _easyRoadNodes.ERRoads.Count; i++) { if (bools.Length > i) { _easyRoadNodes.Inverted.Add(bools[i]); } else { _easyRoadNodes.Inverted.Add(false); } } } if (_easyRoadNodes.OneWay.Count != _easyRoadNodes.ERRoads.Count) { bool[] bools = new bool[_easyRoadNodes.OneWay.Count]; _easyRoadNodes.OneWay.CopyTo(bools); _easyRoadNodes.OneWay.Clear(); for (int i = 0; i < _easyRoadNodes.ERRoads.Count; i++) { if (bools.Length > i) { _easyRoadNodes.OneWay.Add(bools[i]); } else { _easyRoadNodes.OneWay.Add(false); } } } if (_easyRoadNodes.LinesCount.Count != _easyRoadNodes.ERRoads.Count) { int[] ints = new int[_easyRoadNodes.LinesCount.Count]; _easyRoadNodes.LinesCount.CopyTo(ints); _easyRoadNodes.LinesCount.Clear(); for (int i = 0; i < _easyRoadNodes.ERRoads.Count; i++) { if (ints.Length > i) { _easyRoadNodes.LinesCount.Add(ints[i]); } else { _easyRoadNodes.LinesCount.Add(2); } } } GUILayout.BeginHorizontal(); GUILayout.Label("Nodes count:", GUILayout.MaxWidth(230f)); _easyRoadNodes.Count = EditorGUILayout.IntField(_easyRoadNodes.Count, GUILayout.MaxWidth(200f)); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Range between nodes (in meters):", GUILayout.MaxWidth(230f)); _easyRoadNodes.NodeDefinition = EditorGUILayout.FloatField(_easyRoadNodes.NodeDefinition, GUILayout.MaxWidth(200f)); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Count of Bezier curve's points:", GUILayout.MaxWidth(230f)); _easyRoadNodes.Definition = EditorGUILayout.IntField(_easyRoadNodes.Definition, GUILayout.MaxWidth(200f)); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Range for connected nodes search:", GUILayout.MaxWidth(230f)); _easyRoadNodes.MaximumDistance = EditorGUILayout.FloatField(_easyRoadNodes.MaximumDistance, GUILayout.MaxWidth(200f)); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Space(10f); if (_easyRoadNodes.CrossRoads != null) { GUILayout.BeginHorizontal(); GUILayout.Label("Crossroads: " + _easyRoadNodes.CrossRoads.Count, GUILayout.MaxWidth(230f)); GUILayout.EndHorizontal(); if (GUILayout.Button("Regenerate crossroads")) { _easyRoadNodes.RegenerateCrossroads(); } } GUILayout.Space(10f); for (int i = 0; i < _easyRoadNodes.ERRoads.Count; i++) { GUILayout.BeginHorizontal(); if (Selection.activeGameObject == _easyRoadNodes.ERRoads[i].roadScript.transform.gameObject) { GUILayout.Label("=>"); } GUILayout.Label(_easyRoadNodes.ERRoads[i].roadScript.transform.name, GUILayout.MaxWidth(200f)); _easyRoadNodes.DontBuild[i] = GUILayout.Toggle(_easyRoadNodes.DontBuild[i], " Ignore", GUILayout.MaxWidth(70f)); GUILayout.Label("Lines count: "); _easyRoadNodes.LinesCount[i] = EditorGUILayout.IntField(_easyRoadNodes.LinesCount[i], GUILayout.MaxWidth(50f)); _easyRoadNodes.OneWay[i] = GUILayout.Toggle(_easyRoadNodes.OneWay[i], " One way", GUILayout.MaxWidth(70f)); GUI.enabled = _easyRoadNodes.OneWay[i]; _easyRoadNodes.Inverted[i] = GUILayout.Toggle(_easyRoadNodes.Inverted[i], " Invert", GUILayout.MaxWidth(70f)); GUI.enabled = true; GUILayout.Space(5f); if (GUILayout.Button("Rebuild", GUILayout.MaxWidth(100f))) { _easyRoadNodes.GenerateOneRoad(i); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } if (GUILayout.Button(_easyRoadNodes.Generate ? "Generating..." : "Build waypoint network")) { _easyRoadNodes.GenerateNetwork(); } }
private void CreateRoadEntities() { var roadEntityArchetype = entityManager.CreateArchetype( typeof(ERRoadTag), typeof(RoadDetails), typeof(LanePoints) ); var connectionEntityArchetype = entityManager.CreateArchetype( typeof(ERConnectionTag), typeof(ConnectionDetails), typeof(LanePoints) ); int nextRoadIdentity = 0; int nextLaneIndex = 0; int connectionIndexEnd; int connectionIndexStart; int connectionIdentityEnd = 0; int connectionIdentityStart = 0; ERConnection erConnectionEnd; ERConnection erConnectionStart; ERRoadNetwork roadNetwork = new ERRoadNetwork(); ERRoad[] roads = roadNetwork.GetRoads(); List <Vector3> allLanePoints = new List <Vector3>(); List <Vector3> connectionLanePoints = new List <Vector3>(); ConnectedTo connectedTo; //Make entities for each of these objects //Roads first. They need a collection of Lanes and each lane has an input and output connection identity. //This collection of Road Identity & Lane Identity, or Connection Identity & Lane Identity //will be used in the JOB to get the next load of data foreach (ERRoad road in roads) { int roadIdentity = road.gameObject.GetComponent <ERRoadConnectionIdentity>().value; int lanes = road.GetLaneCount(); for (int lane = 0; lane < lanes; lane++) { ERLaneData erLaneData = road.GetLaneData(lane); Vector3[] roadLanePoints = erLaneData.points; if (erLaneData.direction == ERLaneDirection.Right) { erConnectionEnd = road.GetConnectionAtEnd(out connectionIndexEnd); erConnectionStart = road.GetConnectionAtStart(out connectionIndexStart); } else { erConnectionEnd = road.GetConnectionAtStart(out connectionIndexEnd); erConnectionStart = road.GetConnectionAtEnd(out connectionIndexStart); } connectionIdentityStart = RoadConnectionIdentity(erConnectionStart.gameObject); connectionIdentityEnd = RoadConnectionIdentity(erConnectionEnd.gameObject); //Create the Road/Lane entity Entity roadEntity = entityManager.CreateEntity(roadEntityArchetype); entityManager.SetComponentData( roadEntity, new RoadDetails { RoadIdentity = roadIdentity, LaneIndex = erLaneData.laneIndex, ConnectionIdentityEnd = connectionIdentityEnd, ConnectionIdentityStart = connectionIdentityStart, ConnectionIndexEnd = connectionIndexEnd, ConnectionIndexStart = connectionIndexStart }); //Get and store the road's lane points var roadLanePointsBuffer = entityManager.GetBuffer <LanePoints>(roadEntity); var roadLanePoint = new LanePoints(); for (int point = 0; point < roadLanePoints.Length; point++) { roadLanePoint.value = roadLanePoints[point]; roadLanePointsBuffer.Add(roadLanePoint); } //--------------------------------------------------- //Create this Road/Lane/Connection combo ERLaneConnector[] laneConnectors = erConnectionEnd.GetLaneData(connectionIndexEnd, erLaneData.laneIndex); for (int i = 0; i < laneConnectors.Length; i++) { var laneConnector = laneConnectors[i]; var endRoad = erConnectionEnd.GetConnectedRoad(laneConnector.endConnectionIndex, out connectedTo); var roadIdentityEnd = RoadConnectionIdentity(endRoad.gameObject); Entity connectionEntity = entityManager.CreateEntity(connectionEntityArchetype); entityManager.SetComponentData( connectionEntity, new ConnectionDetails { ConnectionIdentity = connectionIdentityEnd, LaneIndexStart = erLaneData.laneIndex, LaneIndexEnd = laneConnector.endLaneIndex, RoadIdentityStart = roadIdentity, RoadIdentityEnd = roadIdentityEnd, ConnectionIndexEnd = laneConnector.endConnectionIndex, ConnectionIndexStart = connectionIndexStart }); var connectionLanePointsBuffer = entityManager.GetBuffer <LanePoints>(connectionEntity); var connectionLanePoint = new LanePoints(); for (int x = 0; x < laneConnector.points.Length; x++) { connectionLanePoint.value = laneConnector.points[x]; connectionLanePointsBuffer.Add(connectionLanePoint); } } //--------------------------------------------------- //Pick a connection and one of the output values to give to the cars that are about to be created int randomValue = UnityEngine.Random.Range(0, laneConnectors.Length); var laneConnect = laneConnectors[randomValue]; var exitRoad = erConnectionEnd.GetConnectedRoad(laneConnect.endConnectionIndex, out connectedTo); nextLaneIndex = laneConnect.endLaneIndex; nextRoadIdentity = RoadConnectionIdentity(exitRoad.gameObject); connectionIndexEnd = laneConnect.endConnectionIndex; connectionLanePoints = laneConnect.points.ToList(); allLanePoints.Clear(); allLanePoints.AddRange(roadLanePoints); allLanePoints.AddRange(connectionLanePoints); connectionLanePoints.Clear(); //Option to not fill every lane int random = UnityEngine.Random.Range(0, 100); if (random <= percentageLanesPopulated) { CreateAutoEntity( allLanePoints, nextLaneIndex, nextRoadIdentity, connectionIdentityEnd, connectionIndexEnd); } } } allLanePoints.Clear(); connectionLanePoints.Clear(); }