- Home /
Question by
SmallGrains · May 30 at 06:15 PM ·
meshmeshrenderermesh renderermesh verticesmesh manipulation
How to generate a track / path mesh using waypoints,How do I generate a track / path mesh using waypoints
I am making a tower defense game, and I need a way to generate a track using waypoints, as all of the waypoints have already been generated using a custom script, but I would want the script to also generate a mesh object, that is the track.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum trackChoice
{
Line,
Rectange,
Curve,
Circle,
};
public enum circleCorner
{
TopLeft,
TopRight,
BottomLeft,
BottomRight,
};
[System.Serializable]
public class Choice_Line
{
public string name = "Line";
public Vector3 StartPosition;
public Vector3 EndPosition;
}
[System.Serializable]
public class Choice_Rectangle
{
public string name = "Rectange";
public Vector3 Position;
public Vector3 Size;
}
[System.Serializable]
public class Choice_Curve
{
public string name = "Curve";
public Vector3 Point1;
public Vector3 Point2;
public bool Invert;
[Header("Calculation Requirement")]
public circleCorner CornerPosition;
public float Angle = 90;
[Header("Calculated")]
public float DistanceToStart;
}
[System.Serializable]
public class Choice_Circle
{
public string name = "Circle";
public Vector3 Position;
public Vector3 Size;
}
[System.Serializable]
public class Track_Choice
{
readonly public string name = "Unchosen";
public trackChoice TrackChoices;
[NonReorderable]
public List<Choice_Line> Line;
[NonReorderable]
public List<Choice_Rectangle> Rectange;
[NonReorderable]
public List<Choice_Curve> Curve;
[NonReorderable]
public List<Choice_Circle> Circle;
}
[ExecuteInEditMode]
public class PathEditor : MonoBehaviour
{
[Header("UNSUPPORTIVE OF 3D TERRAIN")]
private Choice_Line Line;
private Choice_Rectangle Rectange;
private Choice_Curve Curve;
private Choice_Circle Circle;
[SerializeField]
public Track_Choice[] TrackGeneration;
public GameObject RotationHelper;
[Header("Generated Vectors")]
public int PathID;
public bool GenerateVectors;
public List<Vector3> GeneratedTrackVectors;
public bool VisualizeVector3s;
[Header("Generated Track")]
public float TrackSize = 0.5f;
public GameObject TrackObject;
[Header("Setup")]
public bool GenerateSetupObjects;
void Start()
{
}
void Update()
{
if (GenerateSetupObjects)
{
GenerateSetupObjects = false;
if (RotationHelper != null)
DestroyImmediate(RotationHelper);
RotationHelper = new GameObject("Path Editor | Rotation Helper");
}
if (Application.isPlaying)
{
return;
}
if (GenerateVectors)
{
GenerateVectors = false;
Generate();
}
if(VisualizeVector3s)
{
Visualize();
}
//Force One Option
for (int i = 0; i < TrackGeneration.Length; i++)
{
if (TrackGeneration[i].TrackChoices != trackChoice.Line)
TrackGeneration[i].Line.Clear();
if (TrackGeneration[i].TrackChoices != trackChoice.Rectange)
TrackGeneration[i].Rectange.Clear();
if (TrackGeneration[i].TrackChoices != trackChoice.Curve)
TrackGeneration[i].Curve.Clear();
if (TrackGeneration[i].TrackChoices != trackChoice.Circle)
TrackGeneration[i].Circle.Clear();
if (TrackGeneration[i].TrackChoices == trackChoice.Line)
{
if (TrackGeneration[i].Line.Count == 0)
TrackGeneration[i].Line.Add(Line);
if (TrackGeneration[i].Line.Count > 1)
TrackGeneration[i].Line.RemoveRange(1, TrackGeneration[i].Line.Count - 1);
}
if (TrackGeneration[i].TrackChoices == trackChoice.Rectange)
{
if (TrackGeneration[i].Rectange.Count == 0)
TrackGeneration[i].Rectange.Add(Rectange);
if (TrackGeneration[i].Rectange.Count > 1)
TrackGeneration[i].Rectange.RemoveRange(1, TrackGeneration[i].Rectange.Count - 1);
}
if (TrackGeneration[i].TrackChoices == trackChoice.Curve)
{
if (TrackGeneration[i].Curve.Count == 0)
TrackGeneration[i].Curve.Add(Curve);
if (TrackGeneration[i].Curve.Count > 1)
TrackGeneration[i].Curve.RemoveRange(1, TrackGeneration[i].Curve.Count - 1);
}
if (TrackGeneration[i].TrackChoices == trackChoice.Circle)
{
if (TrackGeneration[i].Circle.Count == 0)
TrackGeneration[i].Circle.Add(Circle);
if (TrackGeneration[i].Circle.Count > 1)
TrackGeneration[i].Circle.RemoveRange(1, TrackGeneration[i].Circle.Count - 1);
}
}
}
private void OnDrawGizmos()
{
for (int i = 0; i < TrackGeneration.Length; i++)
{
if (TrackGeneration[i].TrackChoices == trackChoice.Line)
{
Gizmos.DrawLine(TrackGeneration[i].Line[0].StartPosition, TrackGeneration[i].Line[0].EndPosition);
Gizmos.DrawWireSphere(TrackGeneration[i].Line[0].StartPosition, 0.2f);
Gizmos.DrawWireSphere(TrackGeneration[i].Line[0].EndPosition, 0.2f);
}
if (TrackGeneration[i].TrackChoices == trackChoice.Curve)
{
//Order: BottomLeft (Top -> Right) TopLeft (Right -> Bottom) TopRight (Bottom -> Left) BottomRight (Left -> Top)
Vector3 Corner = new Vector3();
Corner.y = TrackGeneration[i].Curve[0].Point1.y;
if (TrackGeneration[i].Curve[0].CornerPosition == circleCorner.TopLeft)
{
Corner.x = Mathf.Min(TrackGeneration[i].Curve[0].Point1.x, TrackGeneration[i].Curve[0].Point2.x);
Corner.z = Mathf.Max(TrackGeneration[i].Curve[0].Point1.z, TrackGeneration[i].Curve[0].Point2.z);
TrackGeneration[i].Curve[0].DistanceToStart = Vector3.Distance(Corner, TrackGeneration[i].Curve[0].Point1);
Vector3 PrevPos = Vector3.zero;
if (TrackGeneration[i].Curve[0].Invert)
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 180, 0);
for (int x = Mathf.CeilToInt(TrackGeneration[i].Curve[0].Angle); x > 0; x--)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 91 + (90 - TrackGeneration[i].Curve[0].Angle), 0);
Gizmos.DrawLine(PrevPos, Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart);
}
}
else
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 90, 0);
for (int x = 0; x < TrackGeneration[i].Curve[0].Angle; x++)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 91, 0);
Gizmos.DrawLine(PrevPos, Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart);
}
}
}
if (TrackGeneration[i].Curve[0].CornerPosition == circleCorner.TopRight)
{
Corner.x = Mathf.Max(TrackGeneration[i].Curve[0].Point1.x, TrackGeneration[i].Curve[0].Point2.x);
Corner.z = Mathf.Max(TrackGeneration[i].Curve[0].Point1.z, TrackGeneration[i].Curve[0].Point2.z);
TrackGeneration[i].Curve[0].DistanceToStart = Vector3.Distance(Corner, TrackGeneration[i].Curve[0].Point1);
Vector3 PrevPos = Vector3.zero;
if (TrackGeneration[i].Curve[0].Invert)
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 270, 0);
for (int x = Mathf.CeilToInt(TrackGeneration[i].Curve[0].Angle); x > 0; x--)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 181 + (90 - TrackGeneration[i].Curve[0].Angle), 0);
Gizmos.DrawLine(PrevPos, Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart);
}
}
else
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 180, 0);
for (int x = 0; x < TrackGeneration[i].Curve[0].Angle; x++)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 181, 0);
Gizmos.DrawLine(PrevPos, Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart);
}
}
}
if (TrackGeneration[i].Curve[0].CornerPosition == circleCorner.BottomLeft)
{
Corner.x = Mathf.Min(TrackGeneration[i].Curve[0].Point1.x, TrackGeneration[i].Curve[0].Point2.x);
Corner.z = Mathf.Min(TrackGeneration[i].Curve[0].Point1.z, TrackGeneration[i].Curve[0].Point2.z);
TrackGeneration[i].Curve[0].DistanceToStart = Vector3.Distance(Corner, TrackGeneration[i].Curve[0].Point1);
Vector3 PrevPos = Vector3.zero;
if (TrackGeneration[i].Curve[0].Invert)
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 90, 0);
for (int x = Mathf.CeilToInt(TrackGeneration[i].Curve[0].Angle); x > 0; x--)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 1 + (90 - TrackGeneration[i].Curve[0].Angle), 0);
Gizmos.DrawLine(PrevPos, Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart);
}
}
else
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 0, 0);
for (int x = 0; x < TrackGeneration[i].Curve[0].Angle; x++)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 1, 0);
Gizmos.DrawLine(PrevPos, Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart);
}
}
}
if (TrackGeneration[i].Curve[0].CornerPosition == circleCorner.BottomRight)
{
Corner.x = Mathf.Max(TrackGeneration[i].Curve[0].Point1.x, TrackGeneration[i].Curve[0].Point2.x);
Corner.z = Mathf.Min(TrackGeneration[i].Curve[0].Point1.z, TrackGeneration[i].Curve[0].Point2.z);
TrackGeneration[i].Curve[0].DistanceToStart = Vector3.Distance(Corner, TrackGeneration[i].Curve[0].Point1);
Vector3 PrevPos = Vector3.zero;
if (TrackGeneration[i].Curve[0].Invert)
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 360, 0);
for (int x = Mathf.CeilToInt(TrackGeneration[i].Curve[0].Angle); x > 0; x--)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 271 + (90 - TrackGeneration[i].Curve[0].Angle), 0);
Gizmos.DrawLine(PrevPos, Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart);
}
}
else
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 270, 0);
for (int x = 0; x < TrackGeneration[i].Curve[0].Angle; x++)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 271, 0);
Gizmos.DrawLine(PrevPos, Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart);
}
}
}
Gizmos.DrawWireCube(Corner, Vector3.one * 0.2f);
Gizmos.DrawWireCube(TrackGeneration[i].Curve[0].Point1, Vector3.one * 0.2f);
Gizmos.DrawWireCube(TrackGeneration[i].Curve[0].Point2, Vector3.one * 0.2f);
}
}
}
void Generate()
{
GeneratedTrackVectors.Clear();
for (int i = 0; i < TrackGeneration.Length; i++)
{
if (TrackGeneration[i].TrackChoices == trackChoice.Line)
{
float Distance = Vector3.Distance(TrackGeneration[i].Line[0].StartPosition, TrackGeneration[i].Line[0].EndPosition);
for (int x = 0; x < Mathf.Ceil(Distance) * 5; x++)
{
GeneratedTrackVectors.Add(Vector3.Lerp(TrackGeneration[i].Line[0].StartPosition, TrackGeneration[i].Line[0].EndPosition,x/ (Mathf.Ceil(Distance) * 5)));
}
}
if (TrackGeneration[i].TrackChoices == trackChoice.Curve)
{
Vector3 Corner = new Vector3();
Corner.y = TrackGeneration[i].Curve[0].Point1.y;
if (TrackGeneration[i].Curve[0].CornerPosition == circleCorner.TopLeft)
{
Corner.x = Mathf.Min(TrackGeneration[i].Curve[0].Point1.x, TrackGeneration[i].Curve[0].Point2.x);
Corner.z = Mathf.Max(TrackGeneration[i].Curve[0].Point1.z, TrackGeneration[i].Curve[0].Point2.z);
Vector3 PrevPos = Vector3.zero;
if (TrackGeneration[i].Curve[0].Invert)
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 180, 0);
for (int x = Mathf.CeilToInt(TrackGeneration[i].Curve[0].Angle); x > 0; x--)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 91 + (90 - TrackGeneration[i].Curve[0].Angle), 0);
if (x == 0 || x % 6 == 0 || x == TrackGeneration[i].Curve[0].Angle)
GeneratedTrackVectors.Add(PrevPos - new Vector3(0, 0, 0));
}
}
else
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 90, 0);
for (int x = 0; x < TrackGeneration[i].Curve[0].Angle + 1; x++)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 91, 0);
if (x == 0 || x % 6 == 0 || x == TrackGeneration[i].Curve[0].Angle)
GeneratedTrackVectors.Add(PrevPos - new Vector3(0, 0, 0));
}
}
}
if (TrackGeneration[i].Curve[0].CornerPosition == circleCorner.TopRight)
{
Corner.x = Mathf.Min(TrackGeneration[i].Curve[0].Point1.x, TrackGeneration[i].Curve[0].Point2.x);
Corner.z = Mathf.Max(TrackGeneration[i].Curve[0].Point1.z, TrackGeneration[i].Curve[0].Point2.z);
Vector3 PrevPos = Vector3.zero;
if (TrackGeneration[i].Curve[0].Invert)
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 270, 0);
for (int x = Mathf.CeilToInt(TrackGeneration[i].Curve[0].Angle); x > 0; x--)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 181 + (90 - TrackGeneration[i].Curve[0].Angle), 0);
if (x == 0 || x % 6 == 0 || x == TrackGeneration[i].Curve[0].Angle)
GeneratedTrackVectors.Add(PrevPos + new Vector3(TrackGeneration[i].Curve[0].DistanceToStart, 0, 0));
}
}
else
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 180, 0);
for (int x = 0; x < TrackGeneration[i].Curve[0].Angle + 1; x++)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 181, 0);
if (x == 0 || x % 6 == 0 || x == TrackGeneration[i].Curve[0].Angle)
GeneratedTrackVectors.Add(PrevPos + new Vector3(TrackGeneration[i].Curve[0].DistanceToStart, 0, 0));
}
}
}
if (TrackGeneration[i].Curve[0].CornerPosition == circleCorner.BottomLeft)
{
Corner.x = Mathf.Min(TrackGeneration[i].Curve[0].Point1.x, TrackGeneration[i].Curve[0].Point2.x);
Corner.z = Mathf.Max(TrackGeneration[i].Curve[0].Point1.z, TrackGeneration[i].Curve[0].Point2.z);
Vector3 PrevPos = Vector3.zero;
if (TrackGeneration[i].Curve[0].Invert)
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 90, 0);
for (int x = Mathf.CeilToInt(TrackGeneration[i].Curve[0].Angle); x > 0; x--)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 1 + (90 - TrackGeneration[i].Curve[0].Angle), 0);
if (x == 0 || x % 6 == 0 || x == TrackGeneration[i].Curve[0].Angle)
GeneratedTrackVectors.Add(PrevPos - new Vector3(0, 0, TrackGeneration[i].Curve[0].DistanceToStart));
}
}
else
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 0, 0);
for (int x = 0; x < TrackGeneration[i].Curve[0].Angle + 1; x++)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 1, 0);
if (x == 0 || x % 6 == 0 || x == TrackGeneration[i].Curve[0].Angle)
GeneratedTrackVectors.Add(PrevPos - new Vector3(0, 0, TrackGeneration[i].Curve[0].DistanceToStart));
}
}
}
if (TrackGeneration[i].Curve[0].CornerPosition == circleCorner.BottomRight)
{
Corner.x = Mathf.Min(TrackGeneration[i].Curve[0].Point1.x, TrackGeneration[i].Curve[0].Point2.x);
Corner.z = Mathf.Max(TrackGeneration[i].Curve[0].Point1.z, TrackGeneration[i].Curve[0].Point2.z);
Vector3 PrevPos = Vector3.zero;
if (TrackGeneration[i].Curve[0].Invert)
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 360, 0);
for (int x = Mathf.CeilToInt(TrackGeneration[i].Curve[0].Angle); x > 0; x--)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 271 + (90 - TrackGeneration[i].Curve[0].Angle), 0);
if (x == 0 || x % 6 == 0 || x == TrackGeneration[i].Curve[0].Angle)
GeneratedTrackVectors.Add(PrevPos - new Vector3(-TrackGeneration[i].Curve[0].DistanceToStart, 0, TrackGeneration[i].Curve[0].DistanceToStart));
}
}
else
{
RotationHelper.transform.rotation = Quaternion.Euler(0, 270, 0);
for (int x = 0; x < TrackGeneration[i].Curve[0].Angle + 1; x++)
{
PrevPos = Corner + RotationHelper.transform.forward * TrackGeneration[i].Curve[0].DistanceToStart;
RotationHelper.transform.rotation = Quaternion.Euler(0, x + 271, 0);
if (x == 0 || x % 6 == 0 || x == TrackGeneration[i].Curve[0].Angle)
GeneratedTrackVectors.Add(PrevPos - new Vector3(-TrackGeneration[i].Curve[0].DistanceToStart, 0, TrackGeneration[i].Curve[0].DistanceToStart));
}
}
}
}
}
GetComponent<GameInfo>().AllPathPoints[PathID].PathPoints.Clear();
GetComponent<GameInfo>().AllPathPoints[PathID].PathPoints.AddRange(GeneratedTrackVectors);
GetComponent<GameInfo>().AllTrackPoints[PathID].TrackPoints.Clear();
GetComponent<GameInfo>().AllTrackPoints[PathID].TrackPoints.AddRange(GeneratedTrackVectors);
int Dels = 1;
GameInfo gI = GetComponent<GameInfo>();
for (int x = 0; x < gI.AllPathPoints[PathID].PathPoints.Count - Dels; x++)
{
if (gI.AllPathPoints[PathID].PathPoints[x] == gI.AllPathPoints[PathID].PathPoints[x + 1])
{
Dels += 1;
gI.AllPathPoints[PathID].PathPoints.RemoveAt(x);
}
}
if (TrackObject == null)
{
TrackObject = new GameObject("Track Visual");
TrackObject.AddComponent<MeshFilter>();
TrackObject.AddComponent<MeshRenderer>();
}
Mesh TrackMesh = new Mesh();
TrackObject.GetComponent<MeshFilter>().mesh = TrackMesh;
}
void Visualize()
{
for (int i = 0; i < GeneratedTrackVectors.Count; i++)
{
Debug.DrawLine(GeneratedTrackVectors[i], GeneratedTrackVectors[i] + new Vector3(0,2,0),Color.red);
}
}
}
,
Comment
Your answer
Follow this Question
Related Questions
Problem with setting vertices positions and smoothing groups. 1 Answer
Flawed Mesh Manipulation Question! 1 Answer
Remove unnecessary vertices from plane mesh 1 Answer
Is it possible to enable Read/Write of a imported Mesh at Runtime? 0 Answers
How do I change the colour of a part of a mesh between vertices? 2 Answers