public Mesh CreateSectionMesh(TrackSection section) { int subdivisions = Mathf.CeilToInt(section.length / length); Mesh mesh = new Mesh(); Vector3[] vertices = new Vector3[2 + subdivisions * 2]; Vector2[] uvs = new Vector2[2 + subdivisions * 2]; int[] triangles = new int[subdivisions * 2 * 6]; int vertexIndex = 0; int triangleIndex = 0; float distance = 0.0f; for (int i = 0; i < subdivisions + 1; i++) { if (i == subdivisions) { distance = section.length; } Vector3 center = section.GetPositionOnTrack(distance).Vector3() - section.position.Vector3() + Vector3.up * 0.01f; Quaternion angle = Quaternion.AngleAxis(270f - (float)section.GetRotationOnTrack(distance).Degrees, Vector3.up); Vector3 tangent = angle * Vector3.forward; Vector3 right = Vector3.Cross(tangent, Vector3.up) * width * 0.5f; Vector3 left = -right; vertices[vertexIndex] = left + center; vertices[vertexIndex + 1] = right + center; uvs[vertexIndex] = new Vector2(0, i); uvs[vertexIndex + 1] = new Vector2(1, i); //Debug.Log("i: " + i + " center: " + center.ToString() + " left: " + left.ToString() + " right " + right.ToString()); if (i > 0.0f) { triangles[triangleIndex] = vertexIndex - 2; triangles[triangleIndex + 1] = vertexIndex + 1; triangles[triangleIndex + 2] = vertexIndex - 1; triangles[triangleIndex + 3] = vertexIndex - 2; triangles[triangleIndex + 4] = vertexIndex; triangles[triangleIndex + 5] = vertexIndex + 1; triangleIndex += 6; } vertexIndex += 2; distance += section.length / (float)subdivisions; } mesh.vertices = vertices; mesh.triangles = triangles; mesh.uv = uvs; //mesh.RecalculateNormals(); return(mesh); }
private Vector3 GetSnappedTrackPosition(TrackSection section, Vector3 point, out float distance) { // TODO: This doesn't find tracks with both endpoints in a different sector than the hit... const float testResolution = 3.0f; distance = 0; float distanceFromPoint = float.MaxValue; float delta = Mathf.Min(testResolution, section.Length / 2); while (distance < section.Length) { var newDistance = distance + delta; var newDistanceFromPoint = Vector3.Distance(point, section.GetPositionOnTrack(newDistance)); if (newDistanceFromPoint > distanceFromPoint) { break; } distance = newDistance; distanceFromPoint = newDistanceFromPoint; } distance = Mathf.Clamp(distance, 0, section.Length); return(section.GetPositionOnTrack(distance)); }
//Warning: Recursive public bool Move(float distance) { bool hasMoved = false; float newPosition = position + distance * (int)direction; if (currentTrackSection.GetPositionOnTrack(newPosition) != null) { //Do the thing position = newPosition; hasMoved = true; } else { TrackSection newSection = (direction == Direction.Forward) ? TrackCollection.instance.Get(currentTrackSection.NextSectionIndex) : TrackCollection.instance.Get(currentTrackSection.PreviousSectionIndex); if (newSection != null) { //Check to see if we need to switch direction Direction newDirection = direction; float distanceOnNewSection = 0.0f; float positionOnNewSection = 0.0f; if (direction == Direction.Forward) { distanceOnNewSection = newPosition - currentTrackSection.length; //TODO: Make a function to determine the correct direction in the TrackSection class //Might be needed when working with switches, so we can override it in that case if (newSection.CheckNextSection(currentTrackSection)) { newDirection = Direction.Reverse; positionOnNewSection = newSection.length; } } else { distanceOnNewSection = -newPosition; positionOnNewSection = newSection.length; if (newSection.CheckPreviousSection(currentTrackSection)) { newDirection = Direction.Forward; positionOnNewSection = 0.0f; } } //TODO: Try to get a stack overflow by calling move with a really high distance value Traveler traveler = new Traveler(newSection, newDirection, positionOnNewSection); hasMoved = traveler.Move(distanceOnNewSection); this.direction = traveler.direction; this.currentTrackSection = traveler.currentTrackSection; this.position = traveler.position; } else { //There was no new section! //TODO: Derail, move to the end or something else? UnityEngine.Debug.Log("Traveler got stuck at track section " + currentTrackSection.index); Derail(); } } return(hasMoved); }
public static void CreateTrackLayout() { TrackCollection trackCollection = TrackCollection.GetInstance(); /* * TrackSection a = new TrackSection(new WorldPosition(0, 0, 20f, 20f), new WorldRotation(25, false), 750f, true, 90f); * trackCollection.Add(a); * TrackSection b = a.CreateNext(750f, true, 90f); * b = b.CreateNext(750f, true, 90f); * b = b.CreateNext(750f, true, 90f); * * b.NextSectionIndex = a.index; * a.PreviousSectionIndex = b.index; */ // Create start section TrackSection start = new TrackSection(new WorldPosition(0, 0, 20f, 10f), new WorldRotation(-100.0f, false), 200.0f); trackCollection.Add(start); TrackSection currentSection = start; currentSection = currentSection.CreateNext(100.0f, false, 0.0f); // Create a new junction TrackJunction junction = new TrackJunction(currentSection.GetPositionOnTrack(currentSection.length), currentSection.GetRotationOnTrack(currentSection.length)); trackCollection.Add(junction); // Attach it to the previous section junction.PreviousSectionIndex = currentSection.index; currentSection.NextSectionIndex = junction.index; // Create the junction sections TrackSection switchSectionCurved = junction.CreateSection(200.0f, true, 90.0f); // 127.32395447351626861510701069801 TrackSection switchSectionStraight = junction.CreateSection(2.0f * 127.32395f, false, 0.0f); // Create a loop currentSection = switchSectionStraight; // NOTE: It's split into two parts because junction sections from the same junction need at least 2 other section before they connect to eachother currentSection = currentSection.CreateNext(200.0f, true, 90.0f); currentSection = currentSection.CreateNext(400.0f, true, 180.0f); // Join it up currentSection.NextSectionIndex = switchSectionCurved.index; switchSectionCurved.NextSectionIndex = currentSection.index; // Create a new piece of track on the other end of the start piece currentSection = new TrackSection(start.position, start.rotation.Oppisite, 20.0f); currentSection.PreviousSectionIndex = start.index; start.PreviousSectionIndex = trackCollection.Add(currentSection); // Create a new junction junction = new TrackJunction(currentSection.GetPositionOnTrack(currentSection.length), currentSection.GetRotationOnTrack(currentSection.length)); trackCollection.Add(junction); // Attach it to the previous section junction.PreviousSectionIndex = currentSection.index; currentSection.NextSectionIndex = junction.index; // Create the junction sections switchSectionCurved = junction.CreateSection(200.0f, true, 90.0f); //127.32395447351626861510701069801 switchSectionStraight = junction.CreateSection(2.0f * 127.32395f, false, 0.0f); // Create a loop currentSection = switchSectionStraight; // NOTE: It's split into two parts because junction sections from the same junction need at least 2 other section before they connect to eachother // Add a junction and attach it junction = new TrackJunction(currentSection.GetPositionOnTrack(currentSection.length), currentSection.GetRotationOnTrack(currentSection.length)); trackCollection.Add(junction); junction.PreviousSectionIndex = currentSection.index; currentSection.NextSectionIndex = junction.index; // Create the curved loop junction section currentSection = junction.CreateSection(200.0f, true, 90.0f); // Create the straight junction section TrackSection branch = junction.CreateSection(200.0f, false, 0.0f); // Finish the loop currentSection = currentSection.CreateNext(400.0f, true, 180.0f); // Join it up currentSection.NextSectionIndex = switchSectionCurved.index; switchSectionCurved.NextSectionIndex = currentSection.index; branch = branch.CreateNext(400, true, 10); branch = branch.CreateNext(100, false, 0); branch = branch.CreateNext(500, true, -20); branch = branch.CreateNext(1000, false, 0); //Save it TrackLayout trackLayout = TrackLayout.CreateFromTrackCollection(trackCollection); AssetDatabase.CreateAsset(trackLayout, "Assets/Resources/DemoTrackLayout.asset"); AssetDatabase.SaveAssets(); EditorUtility.FocusProjectWindow(); Selection.activeObject = trackLayout; }