Quellcode durchsuchen

实现了敌人攀爬树木的功能

Callum vor 3 Monaten
Ursprung
Commit
c0960a40be
100 geänderte Dateien mit 9971 neuen und 0 gelöschten Zeilen
  1. 8 0
      ActionTowerDefense/Assets/PathCreator.meta
  2. 10 0
      ActionTowerDefense/Assets/PathCreator/Core.meta
  3. 8 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor.meta
  4. 8 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper.meta
  5. 45 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/MouseUtility.cs
  6. 11 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/MouseUtility.cs.meta
  7. 243 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/PathHandle.cs
  8. 11 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/PathHandle.cs.meta
  9. 219 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/ScreenSpacePolyLine.cs
  10. 11 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/ScreenSpacePolyLine.cs.meta
  11. 16 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor/PathCreatorEditor.asmdef
  12. 7 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor/PathCreatorEditor.asmdef.meta
  13. 878 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor/PathEditor.cs
  14. 13 0
      ActionTowerDefense/Assets/PathCreator/Core/Editor/PathEditor.cs.meta
  15. 8 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime.meta
  16. 8 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects.meta
  17. 830 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/BezierPath.cs
  18. 13 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/BezierPath.cs.meta
  19. 3 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/EndOfPathInstruction.cs
  20. 11 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/EndOfPathInstruction.cs.meta
  21. 70 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/GlobalDisplaySettings.cs
  22. 11 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/GlobalDisplaySettings.cs.meta
  23. 21 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/MinMax3D.cs
  24. 11 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/MinMax3D.cs.meta
  25. 112 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathCreator.cs
  26. 13 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathCreator.cs.meta
  27. 136 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathCreatorData.cs
  28. 11 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathCreatorData.cs.meta
  29. 3 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathSpace.cs
  30. 11 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathSpace.cs.meta
  31. 355 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/VertexPath.cs
  32. 11 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/VertexPath.cs.meta
  33. 3 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/PathCreator.asmdef
  34. 7 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/PathCreator.asmdef.meta
  35. 8 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility.meta
  36. 136 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/CubicBezierUtility.cs
  37. 13 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/CubicBezierUtility.cs.meta
  38. 168 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/MathUtility.cs
  39. 11 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/MathUtility.cs.meta
  40. 139 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/VertexPathUtility.cs
  41. 11 0
      ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/VertexPathUtility.cs.meta
  42. 8 0
      ActionTowerDefense/Assets/PathCreator/Core/Settings.meta
  43. 36 0
      ActionTowerDefense/Assets/PathCreator/Core/Settings/GlobalDisplaySettings.asset
  44. 8 0
      ActionTowerDefense/Assets/PathCreator/Core/Settings/GlobalDisplaySettings.asset.meta
  45. 8 0
      ActionTowerDefense/Assets/PathCreator/Documentation.meta
  46. BIN
      ActionTowerDefense/Assets/PathCreator/Documentation/Documentation.pdf
  47. 7 0
      ActionTowerDefense/Assets/PathCreator/Documentation/Documentation.pdf.meta
  48. 9 0
      ActionTowerDefense/Assets/PathCreator/Examples.meta
  49. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials.meta
  50. 76 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Black.mat
  51. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Black.mat.meta
  52. 76 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Blue.mat
  53. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Blue.mat.meta
  54. 77 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Brown.mat
  55. 10 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Brown.mat.meta
  56. 77 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Dark Grey.mat
  57. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Dark Grey.mat.meta
  58. 76 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Green.mat
  59. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Green.mat.meta
  60. 76 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Red.mat
  61. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Red.mat.meta
  62. BIN
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road Texture.png
  63. 74 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road Texture.png.meta
  64. 76 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road Underside.mat
  65. 10 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road Underside.mat.meta
  66. 76 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road.mat
  67. 9 0
      ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road.mat.meta
  68. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Prefabs.meta
  69. 79 0
      ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Cube.prefab
  70. 7 0
      ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Cube.prefab.meta
  71. 450 0
      ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Follower.prefab
  72. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Follower.prefab.meta
  73. 106 0
      ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Path.prefab
  74. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Path.prefab.meta
  75. 79 0
      ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Sphere.prefab
  76. 7 0
      ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Sphere.prefab.meta
  77. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes.meta
  78. 393 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Follow Path.unity
  79. 7 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Follow Path.unity.meta
  80. 973 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Generate Path.unity
  81. 7 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Generate Path.unity.meta
  82. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Mesh Examples.meta
  83. 158 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Mesh Examples/Cylinder.unity
  84. 7 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Mesh Examples/Cylinder.unity.meta
  85. 376 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Mesh Examples/Road.unity
  86. 7 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Mesh Examples/Road.unity.meta
  87. 1944 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Object Placement.unity
  88. 7 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Object Placement.unity.meta
  89. 517 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Path as Prefab.unity
  90. 7 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Path as Prefab.unity.meta
  91. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scripts.meta
  92. 115 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scripts/CylinderMeshCreator.cs
  93. 11 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scripts/CylinderMeshCreator.cs.meta
  94. 8 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scripts/Editor.meta
  95. 108 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scripts/Editor/PathSceneToolEditor.cs
  96. 11 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scripts/Editor/PathSceneToolEditor.cs.meta
  97. 20 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scripts/GeneratePathExample.cs
  98. 11 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scripts/GeneratePathExample.cs.meta
  99. 38 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scripts/PathFollower.cs
  100. 11 0
      ActionTowerDefense/Assets/PathCreator/Examples/Scripts/PathFollower.cs.meta

+ 8 - 0
ActionTowerDefense/Assets/PathCreator.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d5bcef90faa7f4dd8a9bc8f2b647be94
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 10 - 0
ActionTowerDefense/Assets/PathCreator/Core.meta

@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: fded9f896ea32473eb30ae61b640a176
+folderAsset: yes
+timeCreated: 1519645413
+licenseType: Pro
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 76c2f3171eae9954aa317277dbffd478
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 366e41d4e3408334aad31e48f28757e4
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 45 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/MouseUtility.cs

@@ -0,0 +1,45 @@
+using UnityEngine;
+using UnityEditor;
+using PathCreation;
+
+namespace PathCreationEditor
+{
+    public static class MouseUtility
+    {
+        /// <summary>
+        /// Determines mouse position in world. If PathSpace is xy/xz, the position will be locked to that plane.
+        /// If PathSpace is xyz, will attempt to raycast to a reasonably close object, or return the position
+        /// at depthFor3DSpace distance from the current view
+        /// </summary>
+        public static Vector3 GetMouseWorldPosition(PathSpace space, float depthFor3DSpace = 10)
+        {
+            var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
+            var worldMouse = Physics.Raycast(mouseRay, out var hitInfo, depthFor3DSpace * 2f) ? 
+                hitInfo.point : mouseRay.GetPoint(depthFor3DSpace);
+
+            // Mouse can only move on XY plane
+            if (space == PathSpace.xy)
+            {
+                var zDir = mouseRay.direction.z;
+                if (zDir != 0)
+                {
+                    var dstToXYPlane = Mathf.Abs(mouseRay.origin.z / zDir);
+                    worldMouse = mouseRay.GetPoint(dstToXYPlane);
+                }
+            }
+            // Mouse can only move on XZ plane 
+            else if (space == PathSpace.xz)
+            {
+                var yDir = mouseRay.direction.y;
+                if (yDir != 0)
+                {
+                    var dstToXZPlane = Mathf.Abs(mouseRay.origin.y / yDir);
+                    worldMouse = mouseRay.GetPoint(dstToXZPlane);
+                }
+            }
+
+            return worldMouse;
+        }
+
+    }
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/MouseUtility.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bd0de63ca5c52504a8d2063418a326c3
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 243 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/PathHandle.cs

@@ -0,0 +1,243 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+using PathCreation;
+
+namespace PathCreationEditor
+{
+	public static class PathHandle
+	{
+
+		public const float extraInputRadius = .005f;
+
+		static Vector2 handleDragMouseStart;
+		static Vector2 handleDragMouseEnd;
+		static Vector3 handleDragWorldStart;
+
+		static int selectedHandleID;
+		static bool mouseIsOverAHandle;
+
+		public enum HandleInputType
+		{
+			None,
+			LMBPress,
+			LMBClick,
+			LMBDrag,
+			LMBRelease,
+		};
+
+		static float dstMouseToDragPointStart;
+
+		static List<int> ids;
+		static HashSet<int> idHash;
+
+		static PathHandle()
+		{
+			ids = new List<int>();
+			idHash = new HashSet<int>();
+
+			dstMouseToDragPointStart = float.MaxValue;
+		}
+
+		public static Vector3 DrawHandle(Vector3 position, PathSpace space, bool isInteractive, float handleDiameter, Handles.CapFunction capFunc, HandleColours colours, out HandleInputType inputType, int handleIndex)
+		{
+			int id = GetID(handleIndex);
+			Vector3 screenPosition = Handles.matrix.MultiplyPoint(position);
+			Matrix4x4 cachedMatrix = Handles.matrix;
+
+			inputType = HandleInputType.None;
+
+			EventType eventType = Event.current.GetTypeForControl(id);
+			float handleRadius = handleDiameter / 2f;
+			float dstToHandle = HandleUtility.DistanceToCircle(position, handleRadius + extraInputRadius);
+			float dstToMouse = HandleUtility.DistanceToCircle(position, 0);
+
+			// Handle input events
+			if (isInteractive)
+			{
+				// Repaint if mouse is entering/exiting handle (for highlight colour)
+				if (dstToHandle == 0)
+				{
+					if (!mouseIsOverAHandle)
+					{
+						HandleUtility.Repaint();
+						mouseIsOverAHandle = true;
+					}
+				}
+				else
+				{
+					if (mouseIsOverAHandle)
+					{
+						HandleUtility.Repaint();
+						mouseIsOverAHandle = false;
+					}
+				}
+				switch (eventType)
+				{
+					case EventType.MouseDown:
+						if (Event.current.button == 0 && Event.current.modifiers != EventModifiers.Alt)
+						{
+							if (dstToHandle == 0 && dstToMouse < dstMouseToDragPointStart)
+							{
+								dstMouseToDragPointStart = dstToMouse;
+								GUIUtility.hotControl = id;
+								handleDragMouseEnd = handleDragMouseStart = Event.current.mousePosition;
+								handleDragWorldStart = position;
+								selectedHandleID = id;
+								inputType = HandleInputType.LMBPress;
+							}
+						}
+						break;
+
+					case EventType.MouseUp:
+						dstMouseToDragPointStart = float.MaxValue;
+						if (GUIUtility.hotControl == id && Event.current.button == 0)
+						{
+							GUIUtility.hotControl = 0;
+							selectedHandleID = -1;
+							Event.current.Use();
+
+							inputType = HandleInputType.LMBRelease;
+
+
+							if (Event.current.mousePosition == handleDragMouseStart)
+							{
+								inputType = HandleInputType.LMBClick;
+							}
+						}
+						break;
+
+					case EventType.MouseDrag:
+						if (GUIUtility.hotControl == id && Event.current.button == 0)
+						{
+							handleDragMouseEnd += new Vector2(Event.current.delta.x, -Event.current.delta.y);
+							Vector3 position2 = Camera.current.WorldToScreenPoint(Handles.matrix.MultiplyPoint(handleDragWorldStart))
+								+ (Vector3)(handleDragMouseEnd - handleDragMouseStart);
+							inputType = HandleInputType.LMBDrag;
+							// Handle can move freely in 3d space
+							if (space == PathSpace.xyz)
+							{
+								position = Handles.matrix.inverse.MultiplyPoint(Camera.current.ScreenToWorldPoint(position2));
+							}
+							// Handle is clamped to xy or xz plane
+							else
+							{
+								position = MouseUtility.GetMouseWorldPosition(space);
+							}
+
+							GUI.changed = true;
+							Event.current.Use();
+						}
+						break;
+				}
+			}
+
+			switch (eventType)
+			{
+				case EventType.Repaint:
+					Color originalColour = Handles.color;
+					Handles.color = (isInteractive) ? colours.defaultColour : colours.disabledColour;
+
+					if (id == GUIUtility.hotControl)
+					{
+						Handles.color = colours.selectedColour;
+					}
+					else if (dstToHandle == 0 && selectedHandleID == -1 && isInteractive)
+					{
+						Handles.color = colours.highlightedColour;
+					}
+
+
+					Handles.matrix = Matrix4x4.identity;
+					Vector3 lookForward = Vector3.zero;
+					Camera cam = Camera.current;
+					if (cam != null)
+					{
+						if (cam.orthographic)
+						{
+							lookForward = -cam.transform.forward;
+						}
+						else
+						{
+							lookForward = (cam.transform.position - position).normalized;
+						}
+					}
+					
+					if (lookForward == Vector3.zero) {
+						lookForward = Vector3.forward;
+					}
+
+					capFunc(id, screenPosition, Quaternion.LookRotation(lookForward), handleDiameter, EventType.Repaint);
+					Handles.matrix = cachedMatrix;
+
+					Handles.color = originalColour;
+					break;
+
+				case EventType.Layout:
+					Handles.matrix = Matrix4x4.identity;
+					HandleUtility.AddControl(id, HandleUtility.DistanceToCircle(screenPosition, handleDiameter / 2f));
+					Handles.matrix = cachedMatrix;
+					break;
+			}
+
+			return position;
+		}
+
+		public struct HandleColours
+		{
+			public Color defaultColour;
+			public Color highlightedColour;
+			public Color selectedColour;
+			public Color disabledColour;
+
+			public HandleColours(Color defaultColour, Color highlightedColour, Color selectedColour, Color disabledColour)
+			{
+				this.defaultColour = defaultColour;
+				this.highlightedColour = highlightedColour;
+				this.selectedColour = selectedColour;
+				this.disabledColour = disabledColour;
+			}
+		}
+
+		static void AddIDs(int upToIndex)
+		{
+			int numIDAtStart = ids.Count;
+			int numToAdd = (upToIndex - numIDAtStart) + 1;
+			for (int i = 0; i < numToAdd; i++)
+			{
+				string hashString = string.Format("pathhandle({0})", numIDAtStart + i);
+				int hash = hashString.GetHashCode();
+
+				int id = GUIUtility.GetControlID(hash, FocusType.Passive);
+				int numIts = 0;
+
+				// This is a bit of a shot in the dark at fixing a reported bug that I've been unable to reproduce.
+				// The problem is that multiple handles are being selected when just one is clicked on.
+				// I assume this is because they're somehow being assigned the same id.
+				while (idHash.Contains(id))
+				{
+					numIts++;
+					id += numIts * numIts;
+					if (numIts > 100)
+					{
+						Debug.LogError("Failed to generate unique handle id.");
+						break;
+					}
+				}
+
+				idHash.Add(id);
+				ids.Add(id);
+			}
+		}
+
+		static int GetID(int handleIndex)
+		{
+			if (handleIndex >= ids.Count)
+			{
+				AddIDs(handleIndex);
+			}
+
+			return ids[handleIndex];
+		}
+	}
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/PathHandle.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 804ddb43548540a4ca3b0a534a75c4b3
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 219 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/ScreenSpacePolyLine.cs

@@ -0,0 +1,219 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+using PathCreation;
+using PathCreation.Utility;
+
+namespace PathCreationEditor
+{
+	public class ScreenSpacePolyLine
+	{
+		const int accuracyMultiplier = 10;
+		// dont allow vertices to be spaced too far apart, as screenspace-worldspace conversion can then be noticeably off
+		const float intermediaryThreshold = .2f;
+
+		public readonly List<Vector3> verticesWorld;
+		// For each point in the polyline, says which bezier segment it belongs to
+		readonly List<int> vertexToPathSegmentMap;
+		// Stores the index in the vertices list where the start point of each segment is
+		readonly int[] segmentStartIndices;
+
+		readonly float pathLengthWorld;
+		readonly float[] cumululativeLengthWorld;
+
+		Vector2[] points;
+
+		Vector3 prevCamPos;
+		Quaternion prevCamRot;
+		bool prevCamIsOrtho;
+
+		readonly Transform transform;
+		readonly Vector3 transformPosition;
+		readonly Quaternion transformRotation;
+		readonly Vector3 transformScale;
+
+		public ScreenSpacePolyLine(BezierPath bezierPath, Transform transform, float maxAngleError, float minVertexDst, float accuracy = 1)
+		{
+			this.transform = transform;
+			transformPosition = transform.position;
+			transformRotation = transform.rotation;
+			transformScale = transform.localScale;
+
+			// Split path in vertices based on angle error
+			verticesWorld = new List<Vector3>();
+			vertexToPathSegmentMap = new List<int>();
+			segmentStartIndices = new int[bezierPath.NumSegments + 1];
+
+			verticesWorld.Add(bezierPath[0]);
+			vertexToPathSegmentMap.Add(0);
+			Vector3 prevPointOnPath = bezierPath[0];
+			float dstSinceLastVertex = 0;
+			Vector3 lastAddedPoint = prevPointOnPath;
+			float dstSinceLastIntermediary = 0;
+
+			for (int segmentIndex = 0; segmentIndex < bezierPath.NumSegments; segmentIndex++)
+			{
+				Vector3[] segmentPoints = bezierPath.GetPointsInSegment(segmentIndex);
+				verticesWorld.Add(segmentPoints[0]);
+				vertexToPathSegmentMap.Add(segmentIndex);
+				segmentStartIndices[segmentIndex] = verticesWorld.Count - 1;
+
+				prevPointOnPath = segmentPoints[0];
+				lastAddedPoint = prevPointOnPath;
+				dstSinceLastVertex = 0;
+				dstSinceLastIntermediary = 0;
+
+				float estimatedSegmentLength = CubicBezierUtility.EstimateCurveLength(segmentPoints[0], segmentPoints[1], segmentPoints[2], segmentPoints[3]);
+				int divisions = Mathf.CeilToInt(estimatedSegmentLength * accuracy * accuracyMultiplier);
+				float increment = 1f / divisions;
+
+				for (float t = increment; t <= 1; t += increment)
+				{
+					Vector3 pointOnPath = CubicBezierUtility.EvaluateCurve(segmentPoints[0], segmentPoints[1], segmentPoints[2], segmentPoints[3], t);
+					Vector3 nextPointOnPath = CubicBezierUtility.EvaluateCurve(segmentPoints[0], segmentPoints[1], segmentPoints[2], segmentPoints[3], t + increment);
+
+					// angle at current point on path
+					float localAngle = 180 - MathUtility.MinAngle(prevPointOnPath, pointOnPath, nextPointOnPath);
+					// angle between the last added vertex, the current point on the path, and the next point on the path
+					float angleFromPrevVertex = 180 - MathUtility.MinAngle(lastAddedPoint, pointOnPath, nextPointOnPath);
+					float angleError = Mathf.Max(localAngle, angleFromPrevVertex);
+
+
+					if (angleError > maxAngleError && dstSinceLastVertex >= minVertexDst)
+					{
+						dstSinceLastVertex = 0;
+						dstSinceLastIntermediary = 0;
+						verticesWorld.Add(pointOnPath);
+						vertexToPathSegmentMap.Add(segmentIndex);
+						lastAddedPoint = pointOnPath;
+					}
+					else
+					{
+						if (dstSinceLastIntermediary > intermediaryThreshold)
+						{
+							verticesWorld.Add(pointOnPath);
+							vertexToPathSegmentMap.Add(segmentIndex);
+							dstSinceLastIntermediary = 0;
+						}
+						else
+						{
+							dstSinceLastIntermediary += (pointOnPath - prevPointOnPath).magnitude;
+						}
+						dstSinceLastVertex += (pointOnPath - prevPointOnPath).magnitude;
+					}
+					prevPointOnPath = pointOnPath;
+				}
+			}
+
+			segmentStartIndices[bezierPath.NumSegments] = verticesWorld.Count;
+
+			// ensure final point gets added (unless path is closed loop)
+			if (!bezierPath.IsClosed)
+			{
+				verticesWorld.Add(bezierPath[bezierPath.NumPoints - 1]);
+			}
+			else
+			{
+				verticesWorld.Add(bezierPath[0]);
+			}
+
+			// Calculate length
+			cumululativeLengthWorld = new float[verticesWorld.Count];
+			for (int i = 0; i < verticesWorld.Count; i++)
+			{
+				verticesWorld[i] = MathUtility.TransformPoint(verticesWorld[i], transform, bezierPath.Space);
+				if (i > 0)
+				{
+					pathLengthWorld += (verticesWorld[i - 1] - verticesWorld[i]).magnitude;
+					cumululativeLengthWorld[i] = pathLengthWorld;
+				}
+			}
+
+		}
+
+		void ComputeScreenSpace()
+		{
+			if (Camera.current.transform.position != prevCamPos || Camera.current.transform.rotation != prevCamRot || Camera.current.orthographic != prevCamIsOrtho)
+			{
+				points = new Vector2[verticesWorld.Count];
+				for (int i = 0; i < verticesWorld.Count; i++)
+				{
+					points[i] = HandleUtility.WorldToGUIPoint(verticesWorld[i]);
+				}
+
+				prevCamPos = Camera.current.transform.position;
+				prevCamRot = Camera.current.transform.rotation;
+				prevCamIsOrtho = Camera.current.orthographic;
+			}
+		}
+
+		public MouseInfo CalculateMouseInfo()
+		{
+			ComputeScreenSpace();
+
+			Vector2 mousePos = Event.current.mousePosition;
+			float minDst = float.MaxValue;
+			int closestPolyLineSegmentIndex = 0;
+			int closestBezierSegmentIndex = 0;
+
+			for (int i = 0; i < points.Length - 1; i++)
+			{
+				float dst = HandleUtility.DistancePointToLineSegment(mousePos, points[i], points[i + 1]);
+
+				if (dst < minDst)
+				{
+					minDst = dst;
+					closestPolyLineSegmentIndex = i;
+					closestBezierSegmentIndex = vertexToPathSegmentMap[i];
+				}
+			}
+
+			Vector2 closestPointOnLine = MathUtility.ClosestPointOnLineSegment(mousePos, points[closestPolyLineSegmentIndex], points[closestPolyLineSegmentIndex + 1]);
+			float dstToPointOnLine = (points[closestPolyLineSegmentIndex] - closestPointOnLine).magnitude;
+
+			float d = (points[closestPolyLineSegmentIndex] - points[closestPolyLineSegmentIndex + 1]).magnitude;
+			float percentBetweenVertices = (d == 0) ? 0 : dstToPointOnLine / d;
+			Vector3 closestPoint3D = Vector3.Lerp(verticesWorld[closestPolyLineSegmentIndex], verticesWorld[closestPolyLineSegmentIndex + 1], percentBetweenVertices);
+
+			float distanceAlongPathWorld = cumululativeLengthWorld[closestPolyLineSegmentIndex] + Vector3.Distance(verticesWorld[closestPolyLineSegmentIndex], closestPoint3D);
+			float timeAlongPath = distanceAlongPathWorld / pathLengthWorld;
+
+			// Calculate how far between the current bezier segment the closest point on the line is
+
+			int bezierSegmentStartIndex = segmentStartIndices[closestBezierSegmentIndex];
+			int bezierSegmentEndIndex = segmentStartIndices[closestBezierSegmentIndex + 1];
+			float bezierSegmentLength = cumululativeLengthWorld[bezierSegmentEndIndex] - cumululativeLengthWorld[bezierSegmentStartIndex];
+			float distanceAlongBezierSegment = distanceAlongPathWorld - cumululativeLengthWorld[bezierSegmentStartIndex];
+			float timeAlongBezierSegment = distanceAlongBezierSegment / bezierSegmentLength;
+
+			return new MouseInfo(minDst, closestPoint3D, distanceAlongPathWorld, timeAlongPath, timeAlongBezierSegment, closestBezierSegmentIndex);
+		}
+
+		public bool TransformIsOutOfDate()
+		{
+			return transform.position != transformPosition || transform.rotation != transformRotation || transform.localScale != transformScale;
+		}
+
+
+		public struct MouseInfo
+		{
+			public readonly float mouseDstToLine;
+			public readonly Vector3 closestWorldPointToMouse;
+			public readonly float distanceAlongPathWorld;
+			public readonly float timeOnPath;
+			public readonly float timeOnBezierSegment;
+			public readonly int closestSegmentIndex;
+
+
+			public MouseInfo(float mouseDstToLine, Vector3 closestWorldPointToMouse, float distanceAlongPathWorld, float timeOnPath, float timeOnBezierSegment, int closestSegmentIndex)
+			{
+				this.mouseDstToLine = mouseDstToLine;
+				this.closestWorldPointToMouse = closestWorldPointToMouse;
+				this.distanceAlongPathWorld = distanceAlongPathWorld;
+				this.timeOnPath = timeOnPath;
+				this.timeOnBezierSegment = timeOnBezierSegment;
+				this.closestSegmentIndex = closestSegmentIndex;
+			}
+		}
+	}
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor/Helper/ScreenSpacePolyLine.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 05aed72a972059e45a62e31c2bb60fc4
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 16 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor/PathCreatorEditor.asmdef

@@ -0,0 +1,16 @@
+{
+    "name": "PathCreatorEditor",
+    "references": [
+        "PathCreator"
+    ],
+    "optionalUnityReferences": [],
+    "includePlatforms": [
+        "Editor"
+    ],
+    "excludePlatforms": [],
+    "allowUnsafeCode": false,
+    "overrideReferences": false,
+    "precompiledReferences": [],
+    "autoReferenced": true,
+    "defineConstraints": []
+}

+ 7 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor/PathCreatorEditor.asmdef.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 92ee438f32d811247a22ca14bf2a3fe0
+AssemblyDefinitionImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 878 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor/PathEditor.cs

@@ -0,0 +1,878 @@
+using System.Collections.Generic;
+using PathCreation;
+using PathCreation.Utility;
+using UnityEditor;
+using UnityEditor.IMGUI.Controls;
+using UnityEngine;
+
+namespace PathCreationEditor
+{
+	/// Editor class for the creation of Bezier and Vertex paths
+
+	[CustomEditor(typeof(PathCreator))]
+	public class PathEditor : Editor
+	{
+
+		#region Fields
+
+		// Interaction:
+		const float segmentSelectDistanceThreshold = 10f;
+		const float screenPolylineMaxAngleError = .3f;
+		const float screenPolylineMinVertexDst = .01f;
+
+		// Help messages:
+		const string helpInfo = "Shift-click to add or insert new points. Control-click to delete points. For more detailed infomation, please refer to the documentation.";
+		static readonly string[] spaceNames = { "3D (xyz)", "2D (xy)", "Top-down (xz)" };
+		static readonly string[] tabNames = { "Bézier Path", "Vertex Path" };
+		const string constantSizeTooltip = "If true, anchor and control points will keep a constant size when zooming in the editor.";
+
+		// Display
+		const int inspectorSectionSpacing = 10;
+		const float constantHandleScale = .01f;
+		const float normalsSpacing = .2f;
+		GUIStyle boldFoldoutStyle;
+
+		// References:
+		PathCreator creator;
+		Editor globalDisplaySettingsEditor;
+		ScreenSpacePolyLine screenSpaceLine;
+		ScreenSpacePolyLine.MouseInfo pathMouseInfo;
+		GlobalDisplaySettings globalDisplaySettings;
+		PathHandle.HandleColours splineAnchorColours;
+		PathHandle.HandleColours splineControlColours;
+		Dictionary<GlobalDisplaySettings.HandleType, Handles.CapFunction> capFunctions;
+		ArcHandle anchorAngleHandle = new ArcHandle();
+		VertexPath normalsVertexPath;
+
+		// State variables:
+		int selectedSegmentIndex;
+		int draggingHandleIndex;
+		int mouseOverHandleIndex;
+		int handleIndexToDisplayAsTransform;
+
+		bool shiftLastFrame;
+		bool hasUpdatedScreenSpaceLine;
+		bool hasUpdatedNormalsVertexPath;
+		bool editingNormalsOld;
+
+		Vector3 transformPos;
+		Vector3 transformScale;
+		Quaternion transformRot;
+
+		Color handlesStartCol;
+
+		// Constants
+		const int bezierPathTab = 0;
+		const int vertexPathTab = 1;
+
+		#endregion
+
+		#region Inspectors
+
+		public override void OnInspectorGUI()
+		{
+			// Initialize GUI styles
+			if (boldFoldoutStyle == null)
+			{
+				boldFoldoutStyle = new GUIStyle(EditorStyles.foldout);
+				boldFoldoutStyle.fontStyle = FontStyle.Bold;
+			}
+
+			Undo.RecordObject(creator, "Path settings changed");
+
+			// Draw Bezier and Vertex tabs
+			int tabIndex = GUILayout.Toolbar(data.tabIndex, tabNames);
+			if (tabIndex != data.tabIndex)
+			{
+				data.tabIndex = tabIndex;
+				TabChanged();
+			}
+
+			// Draw inspector for active tab
+			switch (data.tabIndex)
+			{
+				case bezierPathTab:
+					DrawBezierPathInspector();
+					break;
+				case vertexPathTab:
+					DrawVertexPathInspector();
+					break;
+			}
+
+			// Notify of undo/redo that might modify the path
+			if (Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
+			{
+				data.PathModifiedByUndo();
+			}
+		}
+
+		void DrawBezierPathInspector()
+		{
+			using (var check = new EditorGUI.ChangeCheckScope())
+			{
+				// Path options:
+				data.showPathOptions = EditorGUILayout.Foldout(data.showPathOptions, new GUIContent("Bézier Path Options"), true, boldFoldoutStyle);
+				if (data.showPathOptions)
+				{
+					bezierPath.Space = (PathSpace)EditorGUILayout.Popup("Space", (int)bezierPath.Space, spaceNames);
+					bezierPath.ControlPointMode = (BezierPath.ControlMode)EditorGUILayout.EnumPopup(new GUIContent("Control Mode"), bezierPath.ControlPointMode);
+					if (bezierPath.ControlPointMode == BezierPath.ControlMode.Automatic)
+					{
+						bezierPath.AutoControlLength = EditorGUILayout.Slider(new GUIContent("Control Spacing"), bezierPath.AutoControlLength, 0, 1);
+					}
+
+					bezierPath.IsClosed = EditorGUILayout.Toggle("Closed Path", bezierPath.IsClosed);
+					data.showTransformTool = EditorGUILayout.Toggle(new GUIContent("Enable Transforms"), data.showTransformTool);
+
+					Tools.hidden = !data.showTransformTool;
+
+					// Check if out of bounds (can occur after undo operations)
+					if (handleIndexToDisplayAsTransform >= bezierPath.NumPoints)
+					{
+						handleIndexToDisplayAsTransform = -1;
+					}
+
+					// If a point has been selected
+					if (handleIndexToDisplayAsTransform != -1)
+					{
+						EditorGUILayout.LabelField("Selected Point:");
+
+						using (new EditorGUI.IndentLevelScope())
+						{
+							var currentPosition = creator.bezierPath[handleIndexToDisplayAsTransform];
+							var newPosition = EditorGUILayout.Vector3Field("Position", currentPosition);
+							if (newPosition != currentPosition)
+							{
+								Undo.RecordObject(creator, "Move point");
+								creator.bezierPath.MovePoint(handleIndexToDisplayAsTransform, newPosition);
+							}
+							// Don't draw the angle field if we aren't selecting an anchor point/not in 3d space
+							if (handleIndexToDisplayAsTransform % 3 == 0 && creator.bezierPath.Space == PathSpace.xyz)
+							{
+								var anchorIndex = handleIndexToDisplayAsTransform / 3;
+								var currentAngle = creator.bezierPath.GetAnchorNormalAngle(anchorIndex);
+								var newAngle = EditorGUILayout.FloatField("Angle", currentAngle);
+								if (newAngle != currentAngle)
+								{
+									Undo.RecordObject(creator, "Set Angle");
+									creator.bezierPath.SetAnchorNormalAngle(anchorIndex, newAngle);
+								}
+							}
+						}
+					}
+
+					if (data.showTransformTool & (handleIndexToDisplayAsTransform == -1))
+					{
+						if (GUILayout.Button("Centre Transform"))
+						{
+
+							Vector3 worldCentre = bezierPath.CalculateBoundsWithTransform(creator.transform).center;
+							Vector3 transformPos = creator.transform.position;
+							if (bezierPath.Space == PathSpace.xy)
+							{
+								transformPos = new Vector3(transformPos.x, transformPos.y, 0);
+							}
+							else if (bezierPath.Space == PathSpace.xz)
+							{
+								transformPos = new Vector3(transformPos.x, 0, transformPos.z);
+							}
+							Vector3 worldCentreToTransform = transformPos - worldCentre;
+
+							if (worldCentre != creator.transform.position)
+							{
+								//Undo.RecordObject (creator, "Centralize Transform");
+								if (worldCentreToTransform != Vector3.zero)
+								{
+									Vector3 localCentreToTransform = MathUtility.InverseTransformVector(worldCentreToTransform, creator.transform, bezierPath.Space);
+									for (int i = 0; i < bezierPath.NumPoints; i++)
+									{
+										bezierPath.SetPoint(i, bezierPath.GetPoint(i) + localCentreToTransform, true);
+									}
+								}
+
+								creator.transform.position = worldCentre;
+								bezierPath.NotifyPathModified();
+							}
+						}
+					}
+
+					if (GUILayout.Button("Reset Path"))
+					{
+						Undo.RecordObject(creator, "Reset Path");
+						bool in2DEditorMode = EditorSettings.defaultBehaviorMode == EditorBehaviorMode.Mode2D;
+						data.ResetBezierPath(creator.transform.position, in2DEditorMode);
+						EditorApplication.QueuePlayerLoopUpdate();
+					}
+
+					GUILayout.Space(inspectorSectionSpacing);
+				}
+
+				data.showNormals = EditorGUILayout.Foldout(data.showNormals, new GUIContent("Normals Options"), true, boldFoldoutStyle);
+				if (data.showNormals)
+				{
+					bezierPath.FlipNormals = EditorGUILayout.Toggle(new GUIContent("Flip Normals"), bezierPath.FlipNormals);
+					if (bezierPath.Space == PathSpace.xyz)
+					{
+						bezierPath.GlobalNormalsAngle = EditorGUILayout.Slider(new GUIContent("Global Angle"), bezierPath.GlobalNormalsAngle, 0, 360);
+
+						if (GUILayout.Button("Reset Normals"))
+						{
+							Undo.RecordObject(creator, "Reset Normals");
+							bezierPath.FlipNormals = false;
+							bezierPath.ResetNormalAngles();
+						}
+					}
+					GUILayout.Space(inspectorSectionSpacing);
+				}
+
+				// Editor display options
+				data.showDisplayOptions = EditorGUILayout.Foldout(data.showDisplayOptions, new GUIContent("Display Options"), true, boldFoldoutStyle);
+				if (data.showDisplayOptions)
+				{
+					data.showPathBounds = GUILayout.Toggle(data.showPathBounds, new GUIContent("Show Path Bounds"));
+					data.showPerSegmentBounds = GUILayout.Toggle(data.showPerSegmentBounds, new GUIContent("Show Segment Bounds"));
+					data.displayAnchorPoints = GUILayout.Toggle(data.displayAnchorPoints, new GUIContent("Show Anchor Points"));
+					if (!(bezierPath.ControlPointMode == BezierPath.ControlMode.Automatic && globalDisplaySettings.hideAutoControls))
+					{
+						data.displayControlPoints = GUILayout.Toggle(data.displayControlPoints, new GUIContent("Show Control Points"));
+					}
+					data.keepConstantHandleSize = GUILayout.Toggle(data.keepConstantHandleSize, new GUIContent("Constant Point Size", constantSizeTooltip));
+					data.bezierHandleScale = Mathf.Max(0, EditorGUILayout.FloatField(new GUIContent("Handle Scale"), data.bezierHandleScale));
+					DrawGlobalDisplaySettingsInspector();
+				}
+
+				if (check.changed)
+				{
+					SceneView.RepaintAll();
+					EditorApplication.QueuePlayerLoopUpdate();
+				}
+			}
+		}
+
+		void DrawVertexPathInspector()
+		{
+
+			GUILayout.Space(inspectorSectionSpacing);
+			EditorGUILayout.LabelField("Vertex count: " + creator.path.NumPoints);
+			GUILayout.Space(inspectorSectionSpacing);
+
+			data.showVertexPathOptions = EditorGUILayout.Foldout(data.showVertexPathOptions, new GUIContent("Vertex Path Options"), true, boldFoldoutStyle);
+			if (data.showVertexPathOptions)
+			{
+				using (var check = new EditorGUI.ChangeCheckScope())
+				{
+					data.vertexPathMaxAngleError = EditorGUILayout.Slider(new GUIContent("Max Angle Error"), data.vertexPathMaxAngleError, 0, 45);
+					data.vertexPathMinVertexSpacing = EditorGUILayout.Slider(new GUIContent("Min Vertex Dst"), data.vertexPathMinVertexSpacing, 0, 1);
+
+					GUILayout.Space(inspectorSectionSpacing);
+					if (check.changed)
+					{
+						data.VertexPathSettingsChanged();
+						SceneView.RepaintAll();
+						EditorApplication.QueuePlayerLoopUpdate();
+					}
+				}
+			}
+
+			data.showVertexPathDisplayOptions = EditorGUILayout.Foldout(data.showVertexPathDisplayOptions, new GUIContent("Display Options"), true, boldFoldoutStyle);
+			if (data.showVertexPathDisplayOptions)
+			{
+				using (var check = new EditorGUI.ChangeCheckScope())
+				{
+					data.showNormalsInVertexMode = GUILayout.Toggle(data.showNormalsInVertexMode, new GUIContent("Show Normals"));
+					data.showBezierPathInVertexMode = GUILayout.Toggle(data.showBezierPathInVertexMode, new GUIContent("Show Bezier Path"));
+
+					if (check.changed)
+					{
+						SceneView.RepaintAll();
+						EditorApplication.QueuePlayerLoopUpdate();
+					}
+				}
+				DrawGlobalDisplaySettingsInspector();
+			}
+		}
+
+		void DrawGlobalDisplaySettingsInspector()
+		{
+			using (var check = new EditorGUI.ChangeCheckScope())
+			{
+				data.globalDisplaySettingsFoldout = EditorGUILayout.InspectorTitlebar(data.globalDisplaySettingsFoldout, globalDisplaySettings);
+				if (data.globalDisplaySettingsFoldout)
+				{
+					CreateCachedEditor(globalDisplaySettings, null, ref globalDisplaySettingsEditor);
+					globalDisplaySettingsEditor.OnInspectorGUI();
+				}
+				if (check.changed)
+				{
+					UpdateGlobalDisplaySettings();
+					SceneView.RepaintAll();
+				}
+			}
+		}
+
+		#endregion
+
+		#region Scene GUI
+
+		void OnSceneGUI()
+		{
+			if (!globalDisplaySettings.visibleBehindObjects)
+			{
+				Handles.zTest = UnityEngine.Rendering.CompareFunction.LessEqual;
+			}
+
+			EventType eventType = Event.current.type;
+
+			using (var check = new EditorGUI.ChangeCheckScope())
+			{
+				handlesStartCol = Handles.color;
+				switch (data.tabIndex)
+				{
+					case bezierPathTab:
+						if (eventType != EventType.Repaint && eventType != EventType.Layout)
+						{
+							ProcessBezierPathInput(Event.current);
+						}
+
+						DrawBezierPathSceneEditor();
+						break;
+					case vertexPathTab:
+						if (eventType == EventType.Repaint)
+						{
+							DrawVertexPathSceneEditor();
+						}
+						break;
+				}
+
+				// Don't allow clicking over empty space to deselect the object
+				if (eventType == EventType.Layout)
+				{
+					HandleUtility.AddDefaultControl(0);
+				}
+
+				if (check.changed)
+				{
+					EditorApplication.QueuePlayerLoopUpdate();
+				}
+			}
+
+			SetTransformState();
+		}
+
+		void DrawVertexPathSceneEditor()
+		{
+
+			Color bezierCol = globalDisplaySettings.bezierPath;
+			bezierCol.a *= .5f;
+
+			if (data.showBezierPathInVertexMode)
+			{
+				for (int i = 0; i < bezierPath.NumSegments; i++)
+				{
+					Vector3[] points = bezierPath.GetPointsInSegment(i);
+					for (int j = 0; j < points.Length; j++)
+					{
+						points[j] = MathUtility.TransformPoint(points[j], creator.transform, bezierPath.Space);
+					}
+					Handles.DrawBezier(points[0], points[3], points[1], points[2], bezierCol, null, 2);
+				}
+			}
+
+			Handles.color = globalDisplaySettings.vertexPath;
+
+			for (int i = 0; i < creator.path.NumPoints; i++)
+			{
+				int nextIndex = (i + 1) % creator.path.NumPoints;
+				if (nextIndex != 0 || bezierPath.IsClosed)
+				{
+					Handles.DrawLine(creator.path.GetPoint(i), creator.path.GetPoint(nextIndex));
+				}
+			}
+
+			if (data.showNormalsInVertexMode)
+			{
+				Handles.color = globalDisplaySettings.normals;
+				Vector3[] normalLines = new Vector3[creator.path.NumPoints * 2];
+				for (int i = 0; i < creator.path.NumPoints; i++)
+				{
+					normalLines[i * 2] = creator.path.GetPoint(i);
+					normalLines[i * 2 + 1] = creator.path.GetPoint(i) + creator.path.localNormals[i] * globalDisplaySettings.normalsLength;
+				}
+				Handles.DrawLines(normalLines);
+			}
+		}
+
+		void ProcessBezierPathInput(Event e)
+		{
+			// Find which handle mouse is over. Start by looking at previous handle index first, as most likely to still be closest to mouse
+			int previousMouseOverHandleIndex = (mouseOverHandleIndex == -1) ? 0 : mouseOverHandleIndex;
+			mouseOverHandleIndex = -1;
+			for (int i = 0; i < bezierPath.NumPoints; i += 3)
+			{
+
+				int handleIndex = (previousMouseOverHandleIndex + i) % bezierPath.NumPoints;
+				float handleRadius = GetHandleDiameter(globalDisplaySettings.anchorSize * data.bezierHandleScale, bezierPath[handleIndex]) / 2f;
+				Vector3 pos = MathUtility.TransformPoint(bezierPath[handleIndex], creator.transform, bezierPath.Space);
+				float dst = HandleUtility.DistanceToCircle(pos, handleRadius);
+				if (dst == 0)
+				{
+					mouseOverHandleIndex = handleIndex;
+					break;
+				}
+			}
+
+			// Shift-left click (when mouse not over a handle) to split or add segment
+			if (mouseOverHandleIndex == -1)
+			{
+				if (e.type == EventType.MouseDown && e.button == 0 && e.shift)
+				{
+					UpdatePathMouseInfo();
+					// Insert point along selected segment
+					if (selectedSegmentIndex != -1 && selectedSegmentIndex < bezierPath.NumSegments)
+					{
+						Vector3 newPathPoint = pathMouseInfo.closestWorldPointToMouse;
+						newPathPoint = MathUtility.InverseTransformPoint(newPathPoint, creator.transform, bezierPath.Space);
+						Undo.RecordObject(creator, "Split segment");
+						bezierPath.SplitSegment(newPathPoint, selectedSegmentIndex, pathMouseInfo.timeOnBezierSegment);
+					}
+					// If path is not a closed loop, add new point on to the end of the path
+					else if (!bezierPath.IsClosed)
+					{
+						// If control/command are held down, the point gets pre-pended, so we want to check distance
+						// to the endpoint we are adding to
+						var pointIdx = e.control || e.command ? 0 : bezierPath.NumPoints - 1;
+						// insert new point at same dst from scene camera as the point that comes before it (for a 3d path)
+						var endPointLocal = bezierPath[pointIdx];
+						var endPointGlobal =
+							MathUtility.TransformPoint(endPointLocal, creator.transform, bezierPath.Space);
+						var distanceCameraToEndpoint = (Camera.current.transform.position - endPointGlobal).magnitude;
+						var newPointGlobal =
+							MouseUtility.GetMouseWorldPosition(bezierPath.Space, distanceCameraToEndpoint);
+						var newPointLocal =
+							MathUtility.InverseTransformPoint(newPointGlobal, creator.transform, bezierPath.Space);
+
+						Undo.RecordObject(creator, "Add segment");
+						if (e.control || e.command)
+						{
+							bezierPath.AddSegmentToStart(newPointLocal);
+						}
+						else
+						{
+							bezierPath.AddSegmentToEnd(newPointLocal);
+						}
+
+					}
+
+				}
+			}
+
+			// Control click or backspace/delete to remove point
+			if (e.keyCode == KeyCode.Backspace || e.keyCode == KeyCode.Delete || ((e.control || e.command) && e.type == EventType.MouseDown && e.button == 0))
+			{
+
+				if (mouseOverHandleIndex != -1)
+				{
+					Undo.RecordObject(creator, "Delete segment");
+					bezierPath.DeleteSegment(mouseOverHandleIndex);
+					if (mouseOverHandleIndex == handleIndexToDisplayAsTransform)
+					{
+						handleIndexToDisplayAsTransform = -1;
+					}
+					mouseOverHandleIndex = -1;
+					Repaint();
+				}
+			}
+
+			// Holding shift and moving mouse (but mouse not over a handle/dragging a handle)
+			if (draggingHandleIndex == -1 && mouseOverHandleIndex == -1)
+			{
+				bool shiftDown = e.shift && !shiftLastFrame;
+				if (shiftDown || ((e.type == EventType.MouseMove || e.type == EventType.MouseDrag) && e.shift))
+				{
+					UpdatePathMouseInfo();
+					bool notSplittingAtControlPoint = pathMouseInfo.timeOnBezierSegment > 0 && pathMouseInfo.timeOnBezierSegment < 1;
+					if (pathMouseInfo.mouseDstToLine < segmentSelectDistanceThreshold && notSplittingAtControlPoint)
+					{
+						if (pathMouseInfo.closestSegmentIndex != selectedSegmentIndex)
+						{
+							selectedSegmentIndex = pathMouseInfo.closestSegmentIndex;
+							HandleUtility.Repaint();
+						}
+					}
+					else
+					{
+						selectedSegmentIndex = -1;
+						HandleUtility.Repaint();
+					}
+
+				}
+			}
+
+			shiftLastFrame = e.shift;
+
+		}
+
+		void DrawBezierPathSceneEditor()
+		{
+
+			bool displayControlPoints = data.displayControlPoints && (bezierPath.ControlPointMode != BezierPath.ControlMode.Automatic || !globalDisplaySettings.hideAutoControls);
+			Bounds bounds = bezierPath.CalculateBoundsWithTransform(creator.transform);
+
+			if (Event.current.type == EventType.Repaint)
+			{
+				for (int i = 0; i < bezierPath.NumSegments; i++)
+				{
+					Vector3[] points = bezierPath.GetPointsInSegment(i);
+					for (int j = 0; j < points.Length; j++)
+					{
+						points[j] = MathUtility.TransformPoint(points[j], creator.transform, bezierPath.Space);
+					}
+
+					if (data.showPerSegmentBounds)
+					{
+						Bounds segmentBounds = CubicBezierUtility.CalculateSegmentBounds(points[0], points[1], points[2], points[3]);
+						Handles.color = globalDisplaySettings.segmentBounds;
+						Handles.DrawWireCube(segmentBounds.center, segmentBounds.size);
+					}
+
+					// Draw lines between control points
+					if (displayControlPoints)
+					{
+						Handles.color = (bezierPath.ControlPointMode == BezierPath.ControlMode.Automatic) ? globalDisplaySettings.handleDisabled : globalDisplaySettings.controlLine;
+						Handles.DrawLine(points[1], points[0]);
+						Handles.DrawLine(points[2], points[3]);
+					}
+
+					// Draw path
+					bool highlightSegment = (i == selectedSegmentIndex && Event.current.shift && draggingHandleIndex == -1 && mouseOverHandleIndex == -1);
+					Color segmentCol = (highlightSegment) ? globalDisplaySettings.highlightedPath : globalDisplaySettings.bezierPath;
+					Handles.DrawBezier(points[0], points[3], points[1], points[2], segmentCol, null, 2);
+				}
+
+				if (data.showPathBounds)
+				{
+					Handles.color = globalDisplaySettings.bounds;
+					Handles.DrawWireCube(bounds.center, bounds.size);
+				}
+
+				// Draw normals
+				if (data.showNormals)
+				{
+					if (!hasUpdatedNormalsVertexPath)
+					{
+						normalsVertexPath = new VertexPath(bezierPath, creator.transform, normalsSpacing);
+						hasUpdatedNormalsVertexPath = true;
+					}
+
+					if (editingNormalsOld != data.showNormals)
+					{
+						editingNormalsOld = data.showNormals;
+						Repaint();
+					}
+
+					Vector3[] normalLines = new Vector3[normalsVertexPath.NumPoints * 2];
+					Handles.color = globalDisplaySettings.normals;
+					for (int i = 0; i < normalsVertexPath.NumPoints; i++)
+					{
+						normalLines[i * 2] = normalsVertexPath.GetPoint(i);
+						normalLines[i * 2 + 1] = normalsVertexPath.GetPoint(i) + normalsVertexPath.GetNormal(i) * globalDisplaySettings.normalsLength;
+					}
+					Handles.DrawLines(normalLines);
+				}
+			}
+
+			if (data.displayAnchorPoints)
+			{
+				for (int i = 0; i < bezierPath.NumPoints; i += 3)
+				{
+					DrawHandle(i);
+				}
+			}
+			if (displayControlPoints)
+			{
+				for (int i = 1; i < bezierPath.NumPoints - 1; i += 3)
+				{
+					DrawHandle(i);
+					DrawHandle(i + 1);
+				}
+			}
+		}
+
+		void DrawHandle(int i)
+		{
+			Vector3 handlePosition = MathUtility.TransformPoint(bezierPath[i], creator.transform, bezierPath.Space);
+
+			float anchorHandleSize = GetHandleDiameter(globalDisplaySettings.anchorSize * data.bezierHandleScale, bezierPath[i]);
+			float controlHandleSize = GetHandleDiameter(globalDisplaySettings.controlSize * data.bezierHandleScale, bezierPath[i]);
+
+			bool isAnchorPoint = i % 3 == 0;
+			bool isInteractive = isAnchorPoint || bezierPath.ControlPointMode != BezierPath.ControlMode.Automatic;
+			float handleSize = (isAnchorPoint) ? anchorHandleSize : controlHandleSize;
+			bool doTransformHandle = i == handleIndexToDisplayAsTransform;
+
+			PathHandle.HandleColours handleColours = (isAnchorPoint) ? splineAnchorColours : splineControlColours;
+			if (i == handleIndexToDisplayAsTransform)
+			{
+				handleColours.defaultColour = (isAnchorPoint) ? globalDisplaySettings.anchorSelected : globalDisplaySettings.controlSelected;
+			}
+			var cap = capFunctions[(isAnchorPoint) ? globalDisplaySettings.anchorShape : globalDisplaySettings.controlShape];
+			PathHandle.HandleInputType handleInputType;
+			handlePosition = PathHandle.DrawHandle(handlePosition, bezierPath.Space, isInteractive, handleSize, cap, handleColours, out handleInputType, i);
+
+			if (doTransformHandle)
+			{
+				// Show normals rotate tool 
+				if (data.showNormals && Tools.current == Tool.Rotate && isAnchorPoint && bezierPath.Space == PathSpace.xyz)
+				{
+					Handles.color = handlesStartCol;
+
+					int attachedControlIndex = (i == bezierPath.NumPoints - 1) ? i - 1 : i + 1;
+					Vector3 dir = (bezierPath[attachedControlIndex] - handlePosition).normalized;
+					float handleRotOffset = (360 + bezierPath.GlobalNormalsAngle) % 360;
+					anchorAngleHandle.radius = handleSize * 3;
+					anchorAngleHandle.angle = handleRotOffset + bezierPath.GetAnchorNormalAngle(i / 3);
+					Vector3 handleDirection = Vector3.Cross(dir, Vector3.up);
+					Matrix4x4 handleMatrix = Matrix4x4.TRS(
+						handlePosition,
+						Quaternion.LookRotation(handleDirection, dir),
+						Vector3.one
+					);
+
+					using (new Handles.DrawingScope(handleMatrix))
+					{
+						// draw the handle
+						EditorGUI.BeginChangeCheck();
+						anchorAngleHandle.DrawHandle();
+						if (EditorGUI.EndChangeCheck())
+						{
+							Undo.RecordObject(creator, "Set angle");
+							bezierPath.SetAnchorNormalAngle(i / 3, anchorAngleHandle.angle - handleRotOffset);
+						}
+					}
+
+				}
+				else
+				{
+					handlePosition = Handles.DoPositionHandle(handlePosition, Quaternion.identity);
+				}
+
+			}
+
+			switch (handleInputType)
+			{
+				case PathHandle.HandleInputType.LMBDrag:
+					draggingHandleIndex = i;
+					handleIndexToDisplayAsTransform = -1;
+					Repaint();
+					break;
+				case PathHandle.HandleInputType.LMBRelease:
+					draggingHandleIndex = -1;
+					handleIndexToDisplayAsTransform = -1;
+					Repaint();
+					break;
+				case PathHandle.HandleInputType.LMBClick:
+					draggingHandleIndex = -1;
+					if (Event.current.shift)
+					{
+						handleIndexToDisplayAsTransform = -1; // disable move tool if new point added
+					}
+					else
+					{
+						if (handleIndexToDisplayAsTransform == i)
+						{
+							handleIndexToDisplayAsTransform = -1; // disable move tool if clicking on point under move tool
+						}
+						else
+						{
+							handleIndexToDisplayAsTransform = i;
+						}
+					}
+					Repaint();
+					break;
+				case PathHandle.HandleInputType.LMBPress:
+					if (handleIndexToDisplayAsTransform != i)
+					{
+						handleIndexToDisplayAsTransform = -1;
+						Repaint();
+					}
+					break;
+			}
+
+			Vector3 localHandlePosition = MathUtility.InverseTransformPoint(handlePosition, creator.transform, bezierPath.Space);
+
+			if (bezierPath[i] != localHandlePosition)
+			{
+				Undo.RecordObject(creator, "Move point");
+				bezierPath.MovePoint(i, localHandlePosition);
+
+			}
+
+		}
+
+		#endregion
+
+		#region Internal methods
+
+		void OnDisable()
+		{
+			Tools.hidden = false;
+		}
+
+		void OnEnable()
+		{
+			creator = (PathCreator)target;
+			bool in2DEditorMode = EditorSettings.defaultBehaviorMode == EditorBehaviorMode.Mode2D;
+			creator.InitializeEditorData(in2DEditorMode);
+
+			data.bezierCreated -= ResetState;
+			data.bezierCreated += ResetState;
+			Undo.undoRedoPerformed -= OnUndoRedo;
+			Undo.undoRedoPerformed += OnUndoRedo;
+
+			LoadDisplaySettings();
+			UpdateGlobalDisplaySettings();
+			ResetState();
+			SetTransformState(true);
+		}
+
+		void SetTransformState(bool initialize = false)
+		{
+			Transform t = creator.transform;
+			if (!initialize)
+			{
+				if (transformPos != t.position || t.localScale != transformScale || t.rotation != transformRot)
+				{
+					data.PathTransformed();
+				}
+			}
+			transformPos = t.position;
+			transformScale = t.localScale;
+			transformRot = t.rotation;
+		}
+
+		void OnUndoRedo()
+		{
+			hasUpdatedScreenSpaceLine = false;
+			hasUpdatedNormalsVertexPath = false;
+			selectedSegmentIndex = -1;
+
+			Repaint();
+		}
+
+		void TabChanged()
+		{
+			SceneView.RepaintAll();
+			RepaintUnfocusedSceneViews();
+		}
+
+		void LoadDisplaySettings()
+		{
+			globalDisplaySettings = GlobalDisplaySettings.Load();
+
+			capFunctions = new Dictionary<GlobalDisplaySettings.HandleType, Handles.CapFunction>();
+			capFunctions.Add(GlobalDisplaySettings.HandleType.Circle, Handles.CylinderHandleCap);
+			capFunctions.Add(GlobalDisplaySettings.HandleType.Sphere, Handles.SphereHandleCap);
+			capFunctions.Add(GlobalDisplaySettings.HandleType.Square, Handles.CubeHandleCap);
+		}
+
+		void UpdateGlobalDisplaySettings()
+		{
+			var gds = globalDisplaySettings;
+			splineAnchorColours = new PathHandle.HandleColours(gds.anchor, gds.anchorHighlighted, gds.anchorSelected, gds.handleDisabled);
+			splineControlColours = new PathHandle.HandleColours(gds.control, gds.controlHighlighted, gds.controlSelected, gds.handleDisabled);
+
+			anchorAngleHandle.fillColor = new Color(1, 1, 1, .05f);
+			anchorAngleHandle.wireframeColor = Color.grey;
+			anchorAngleHandle.radiusHandleColor = Color.clear;
+			anchorAngleHandle.angleHandleColor = Color.white;
+		}
+
+		void ResetState()
+		{
+			selectedSegmentIndex = -1;
+			draggingHandleIndex = -1;
+			mouseOverHandleIndex = -1;
+			handleIndexToDisplayAsTransform = -1;
+			hasUpdatedScreenSpaceLine = false;
+			hasUpdatedNormalsVertexPath = false;
+
+			bezierPath.OnModified -= OnPathModifed;
+			bezierPath.OnModified += OnPathModifed;
+
+			SceneView.RepaintAll();
+			EditorApplication.QueuePlayerLoopUpdate();
+		}
+
+		void OnPathModifed()
+		{
+			hasUpdatedScreenSpaceLine = false;
+			hasUpdatedNormalsVertexPath = false;
+
+			RepaintUnfocusedSceneViews();
+		}
+
+		void RepaintUnfocusedSceneViews()
+		{
+			// If multiple scene views are open, repaint those which do not have focus.
+			if (SceneView.sceneViews.Count > 1)
+			{
+				foreach (SceneView sv in SceneView.sceneViews)
+				{
+					if (EditorWindow.focusedWindow != (EditorWindow)sv)
+					{
+						sv.Repaint();
+					}
+				}
+			}
+		}
+
+		void UpdatePathMouseInfo()
+		{
+
+			if (!hasUpdatedScreenSpaceLine || (screenSpaceLine != null && screenSpaceLine.TransformIsOutOfDate()))
+			{
+				screenSpaceLine = new ScreenSpacePolyLine(bezierPath, creator.transform, screenPolylineMaxAngleError, screenPolylineMinVertexDst);
+				hasUpdatedScreenSpaceLine = true;
+			}
+			pathMouseInfo = screenSpaceLine.CalculateMouseInfo();
+		}
+
+		float GetHandleDiameter(float diameter, Vector3 handlePosition)
+		{
+			float scaledDiameter = diameter * constantHandleScale;
+			if (data.keepConstantHandleSize)
+			{
+				scaledDiameter *= HandleUtility.GetHandleSize(handlePosition) * 2.5f;
+			}
+			return scaledDiameter;
+		}
+
+		BezierPath bezierPath
+		{
+			get
+			{
+				return data.bezierPath;
+			}
+		}
+
+		PathCreatorData data
+		{
+			get
+			{
+				return creator.EditorData;
+			}
+		}
+
+		bool editingNormals
+		{
+			get
+			{
+				return Tools.current == Tool.Rotate && handleIndexToDisplayAsTransform % 3 == 0 && bezierPath.Space == PathSpace.xyz;
+			}
+		}
+
+		#endregion
+
+	}
+
+}

+ 13 - 0
ActionTowerDefense/Assets/PathCreator/Core/Editor/PathEditor.cs.meta

@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: 45d81a20743ff42a3b0dfbd499d4797e
+timeCreated: 1516864234
+licenseType: Pro
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c62dae0f992c5174a951248617cc5720
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 2b76edb14a39ed944b9c906e5f1d3aaa
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 830 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/BezierPath.cs

@@ -0,0 +1,830 @@
+using System.Collections.Generic;
+using System.Linq;
+using PathCreation.Utility;
+using UnityEngine;
+
+namespace PathCreation
+{
+	/// A bezier path is a path made by stitching together any number of (cubic) bezier curves.
+	/// A single cubic bezier curve is defined by 4 points: anchor1, control1, control2, anchor2
+	/// The curve moves between the 2 anchors, and the shape of the curve is affected by the positions of the 2 control points
+
+	/// When two curves are stitched together, they share an anchor point (end anchor of curve 1 = start anchor of curve 2).
+	/// So while one curve alone consists of 4 points, two curves are defined by 7 unique points.
+
+	/// Apart from storing the points, this class also provides methods for working with the path.
+	/// For example, adding, inserting, and deleting points.
+
+	[System.Serializable]
+	public class BezierPath
+	{
+		public event System.Action OnModified;
+		public enum ControlMode { Aligned, Mirrored, Free, Automatic };
+
+		#region Fields
+
+		[SerializeField, HideInInspector]
+		List<Vector3> points;
+		[SerializeField, HideInInspector]
+		bool isClosed;
+		[SerializeField, HideInInspector]
+		PathSpace space;
+		[SerializeField, HideInInspector]
+		ControlMode controlMode;
+		[SerializeField, HideInInspector]
+		float autoControlLength = .3f;
+		[SerializeField, HideInInspector]
+		bool boundsUpToDate;
+		[SerializeField, HideInInspector]
+		Bounds bounds;
+
+		// Normals settings
+		[SerializeField, HideInInspector]
+		List<float> perAnchorNormalsAngle;
+		[SerializeField, HideInInspector]
+		float globalNormalsAngle;
+		[SerializeField, HideInInspector]
+		bool flipNormals;
+
+        #endregion
+
+        #region Constructors
+        public BezierPath() : this(Vector3.zero, false, PathSpace.xyz) { }
+
+        /// <summary> Creates a two-anchor path centred around the given centre point </summary>
+        ///<param name="isClosed"> Should the end point connect back to the start point? </param>
+        ///<param name="space"> Determines if the path is in 3d space, or clamped to the xy/xz plane </param>
+        public BezierPath(Vector3 centre, bool isClosed = false, PathSpace space = PathSpace.xyz)
+		{
+
+			Vector3 dir = (space == PathSpace.xz) ? Vector3.forward : Vector3.up;
+			float width = 2;
+			float controlHeight = .5f;
+			float controlWidth = 1f;
+			points = new List<Vector3> {
+ centre + Vector3.left * width,
+ centre + Vector3.left * controlWidth + dir * controlHeight,
+ centre + Vector3.right * controlWidth - dir * controlHeight,
+ centre + Vector3.right * width
+ };
+
+			perAnchorNormalsAngle = new List<float>() { 0, 0 };
+
+			Space = space;
+			IsClosed = isClosed;
+		}
+
+		/// <summary> Creates a path from the supplied 3D points </summary>
+		///<param name="points"> List or array of points to create the path from. </param>
+		///<param name="isClosed"> Should the end point connect back to the start point? </param>
+		///<param name="space"> Determines if the path is in 3d space, or clamped to the xy/xz plane </param>
+		public BezierPath(IEnumerable<Vector3> points, bool isClosed = false, PathSpace space = PathSpace.xyz)
+		{
+			Vector3[] pointsArray = points.ToArray();
+
+			if (pointsArray.Length < 2)
+			{
+				Debug.LogError("Path requires at least 2 anchor points.");
+			}
+			else
+			{
+				controlMode = ControlMode.Automatic;
+				this.points = new List<Vector3> { pointsArray[0], Vector3.zero, Vector3.zero, pointsArray[1] };
+				perAnchorNormalsAngle = new List<float>(new float[] { 0, 0 });
+
+				for (int i = 2; i < pointsArray.Length; i++)
+				{
+					AddSegmentToEnd(pointsArray[i]);
+					perAnchorNormalsAngle.Add(0);
+				}
+			}
+
+			this.Space = space;
+			this.IsClosed = isClosed;
+		}
+
+		/// <summary> Creates a path from the positions of the supplied 2D points </summary>
+		///<param name="transforms"> List or array of transforms to create the path from. </param>
+		///<param name="isClosed"> Should the end point connect back to the start point? </param>
+		///<param name="space"> Determines if the path is in 3d space, or clamped to the xy/xz plane </param>
+		public BezierPath(IEnumerable<Vector2> transforms, bool isClosed = false, PathSpace space = PathSpace.xy) :
+			this(transforms.Select(p => new Vector3(p.x, p.y)), isClosed, space)
+		{ }
+
+		/// <summary> Creates a path from the positions of the supplied transforms </summary>
+		///<param name="transforms"> List or array of transforms to create the path from. </param>
+		///<param name="isClosed"> Should the end point connect back to the start point? </param>
+		///<param name="space"> Determines if the path is in 3d space, or clamped to the xy/xz plane </param>
+		public BezierPath(IEnumerable<Transform> transforms, bool isClosed = false, PathSpace space = PathSpace.xy) :
+			this(transforms.Select(t => t.position), isClosed, space)
+		{ }
+
+		/// <summary> Creates a path from the supplied 2D points </summary>
+		///<param name="points"> List or array of 2d points to create the path from. </param>
+		///<param name="isClosed"> Should the end point connect back to the start point? </param>
+		///<param name="pathSpace"> Determines if the path is in 3d space, or clamped to the xy/xz plane </param>
+		public BezierPath(IEnumerable<Vector2> points, PathSpace space = PathSpace.xyz, bool isClosed = false) :
+			this(points.Select(p => new Vector3(p.x, p.y)), isClosed, space)
+		{ }
+
+		#endregion
+
+		#region Public methods and accessors
+
+		/// Get world space position of point
+		public Vector3 this[int i]
+		{
+			get
+			{
+				return GetPoint(i);
+			}
+		}
+
+		/// Get world space position of point
+		public Vector3 GetPoint(int i)
+		{
+			return points[i];
+		}
+
+		/// Get world space position of point
+		public void SetPoint(int i, Vector3 localPosition, bool suppressPathModifiedEvent = false)
+		{
+			points[i] = localPosition;
+			if (!suppressPathModifiedEvent)
+			{
+				NotifyPathModified();
+			}
+		}
+
+		/// Total number of points in the path (anchors and controls)
+		public int NumPoints
+		{
+			get
+			{
+				return points.Count;
+			}
+		}
+
+		/// Number of anchor points making up the path
+		public int NumAnchorPoints
+		{
+			get
+			{
+				return (IsClosed) ? points.Count / 3 : (points.Count + 2) / 3;
+			}
+		}
+
+		/// Number of bezier curves making up this path
+		public int NumSegments
+		{
+			get
+			{
+				return points.Count / 3;
+			}
+		}
+
+		/// Path can exist in 3D (xyz), 2D (xy), or Top-Down (xz) space
+		/// In xy or xz space, points will be clamped to that plane (so in a 2D path, for example, points will always be at 0 on z axis)
+		public PathSpace Space
+		{
+			get
+			{
+				return space;
+			}
+			set
+			{
+				if (value != space)
+				{
+					PathSpace previousSpace = space;
+					space = value;
+					UpdateToNewPathSpace(previousSpace);
+				}
+			}
+		}
+
+		/// If closed, path will loop back from end point to start point
+		public bool IsClosed
+		{
+			get
+			{
+				return isClosed;
+			}
+			set
+			{
+				if (isClosed != value)
+				{
+					isClosed = value;
+					UpdateClosedState();
+				}
+			}
+		}
+
+		/// The control mode determines the behaviour of control points.
+		/// Possible modes are:
+		/// Aligned = controls stay in straight line around their anchor
+		/// Mirrored = controls stay in straight, equidistant line around their anchor
+		/// Free = no constraints (use this if sharp corners are needed)
+		/// Automatic = controls placed automatically to try make the path smooth
+		public ControlMode ControlPointMode
+		{
+			get
+			{
+				return controlMode;
+			}
+			set
+			{
+				if (controlMode != value)
+				{
+					controlMode = value;
+					if (controlMode == ControlMode.Automatic)
+					{
+						AutoSetAllControlPoints();
+						NotifyPathModified();
+					}
+				}
+			}
+		}
+
+		/// When using automatic control point placement, this value scales how far apart controls are placed
+		public float AutoControlLength
+		{
+			get
+			{
+				return autoControlLength;
+			}
+			set
+			{
+				value = Mathf.Max(value, .01f);
+				if (autoControlLength != value)
+				{
+					autoControlLength = value;
+					AutoSetAllControlPoints();
+					NotifyPathModified();
+				}
+			}
+		}
+
+		/// Add new anchor point to end of the path
+		public void AddSegmentToEnd(Vector3 anchorPos)
+		{
+			if (isClosed)
+			{
+				return;
+			}
+
+			int lastAnchorIndex = points.Count - 1;
+			// Set position for new control to be mirror of its counterpart
+			Vector3 secondControlForOldLastAnchorOffset = (points[lastAnchorIndex] - points[lastAnchorIndex - 1]);
+			if (controlMode != ControlMode.Mirrored && controlMode != ControlMode.Automatic)
+			{
+				// Set position for new control to be aligned with its counterpart, but with a length of half the distance from prev to new anchor
+				float dstPrevToNewAnchor = (points[lastAnchorIndex] - anchorPos).magnitude;
+				secondControlForOldLastAnchorOffset = (points[lastAnchorIndex] - points[lastAnchorIndex - 1]).normalized * dstPrevToNewAnchor * .5f;
+			}
+			Vector3 secondControlForOldLastAnchor = points[lastAnchorIndex] + secondControlForOldLastAnchorOffset;
+			Vector3 controlForNewAnchor = (anchorPos + secondControlForOldLastAnchor) * .5f;
+
+			points.Add(secondControlForOldLastAnchor);
+			points.Add(controlForNewAnchor);
+			points.Add(anchorPos);
+			perAnchorNormalsAngle.Add(perAnchorNormalsAngle[perAnchorNormalsAngle.Count - 1]);
+
+			if (controlMode == ControlMode.Automatic)
+			{
+				AutoSetAllAffectedControlPoints(points.Count - 1);
+			}
+
+			NotifyPathModified();
+		}
+
+		/// Add new anchor point to start of the path
+		public void AddSegmentToStart(Vector3 anchorPos)
+		{
+			if (isClosed)
+			{
+				return;
+			}
+
+			// Set position for new control to be mirror of its counterpart
+			Vector3 secondControlForOldFirstAnchorOffset = (points[0] - points[1]);
+			if (controlMode != ControlMode.Mirrored && controlMode != ControlMode.Automatic)
+			{
+				// Set position for new control to be aligned with its counterpart, but with a length of half the distance from prev to new anchor
+				float dstPrevToNewAnchor = (points[0] - anchorPos).magnitude;
+				secondControlForOldFirstAnchorOffset = secondControlForOldFirstAnchorOffset.normalized * dstPrevToNewAnchor * .5f;
+			}
+
+			Vector3 secondControlForOldFirstAnchor = points[0] + secondControlForOldFirstAnchorOffset;
+			Vector3 controlForNewAnchor = (anchorPos + secondControlForOldFirstAnchor) * .5f;
+			points.Insert(0, anchorPos);
+			points.Insert(1, controlForNewAnchor);
+			points.Insert(2, secondControlForOldFirstAnchor);
+			perAnchorNormalsAngle.Insert(0, perAnchorNormalsAngle[0]);
+
+			if (controlMode == ControlMode.Automatic)
+			{
+				AutoSetAllAffectedControlPoints(0);
+			}
+			NotifyPathModified();
+		}
+
+		/// Insert new anchor point at given position. Automatically place control points around it so as to keep shape of curve the same
+		public void SplitSegment(Vector3 anchorPos, int segmentIndex, float splitTime)
+		{
+			if (float.IsNaN(splitTime))
+			{
+				Debug.Log("Trying to split segment, but given value was invalid");
+				return;
+			}
+
+			splitTime = Mathf.Clamp01(splitTime);
+
+			if (controlMode == ControlMode.Automatic)
+			{
+				points.InsertRange(segmentIndex * 3 + 2, new Vector3[] { Vector3.zero, anchorPos, Vector3.zero });
+				AutoSetAllAffectedControlPoints(segmentIndex * 3 + 3);
+			}
+			else
+			{
+				// Split the curve to find where control points can be inserted to least affect shape of curve
+				// Curve will probably be deformed slightly since splitTime is only an estimate (for performance reasons, and so doesn't correspond exactly with anchorPos)
+				Vector3[][] splitSegment = CubicBezierUtility.SplitCurve(GetPointsInSegment(segmentIndex), splitTime);
+				points.InsertRange(segmentIndex * 3 + 2, new Vector3[] { splitSegment[0][2], splitSegment[1][0], splitSegment[1][1] });
+				int newAnchorIndex = segmentIndex * 3 + 3;
+				MovePoint(newAnchorIndex - 2, splitSegment[0][1], true);
+				MovePoint(newAnchorIndex + 2, splitSegment[1][2], true);
+				MovePoint(newAnchorIndex, anchorPos, true);
+
+				if (controlMode == ControlMode.Mirrored)
+				{
+					float avgDst = ((splitSegment[0][2] - anchorPos).magnitude + (splitSegment[1][1] - anchorPos).magnitude) / 2;
+					MovePoint(newAnchorIndex + 1, anchorPos + (splitSegment[1][1] - anchorPos).normalized * avgDst, true);
+				}
+			}
+
+			// Insert angle for new anchor (value should be set inbetween neighbour anchor angles)
+			int newAnchorAngleIndex = (segmentIndex + 1) % perAnchorNormalsAngle.Count;
+			int numAngles = perAnchorNormalsAngle.Count;
+			float anglePrev = perAnchorNormalsAngle[segmentIndex];
+			float angleNext = perAnchorNormalsAngle[newAnchorAngleIndex];
+			float splitAngle = Mathf.LerpAngle(anglePrev, angleNext, splitTime);
+			perAnchorNormalsAngle.Insert(newAnchorAngleIndex, splitAngle);
+
+			NotifyPathModified();
+		}
+
+		/// Delete the anchor point at given index, as well as its associated control points
+		public void DeleteSegment(int anchorIndex)
+		{
+			// Don't delete segment if its the last one remaining (or if only two segments in a closed path)
+			if (NumSegments > 2 || !isClosed && NumSegments > 1)
+			{
+				if (anchorIndex == 0)
+				{
+					if (isClosed)
+					{
+						points[points.Count - 1] = points[2];
+					}
+					points.RemoveRange(0, 3);
+				}
+				else if (anchorIndex == points.Count - 1 && !isClosed)
+				{
+					points.RemoveRange(anchorIndex - 2, 3);
+				}
+				else
+				{
+					points.RemoveRange(anchorIndex - 1, 3);
+				}
+
+				perAnchorNormalsAngle.RemoveAt(anchorIndex / 3);
+
+				if (controlMode == ControlMode.Automatic)
+				{
+					AutoSetAllControlPoints();
+				}
+
+				NotifyPathModified();
+			}
+		}
+
+		/// Returns an array of the 4 points making up the segment (anchor1, control1, control2, anchor2)
+		public Vector3[] GetPointsInSegment(int segmentIndex)
+		{
+			segmentIndex = Mathf.Clamp(segmentIndex, 0, NumSegments - 1);
+			return new Vector3[] { this[segmentIndex * 3], this[segmentIndex * 3 + 1], this[segmentIndex * 3 + 2], this[LoopIndex(segmentIndex * 3 + 3)] };
+		}
+
+		/// Move an existing point to a new position
+		public void MovePoint(int i, Vector3 pointPos, bool suppressPathModifiedEvent = false)
+		{
+
+			if (space == PathSpace.xy)
+			{
+				pointPos.z = 0;
+			}
+			else if (space == PathSpace.xz)
+			{
+				pointPos.y = 0;
+			}
+			Vector3 deltaMove = pointPos - points[i];
+			bool isAnchorPoint = i % 3 == 0;
+
+			// Don't process control point if control mode is set to automatic
+			if (isAnchorPoint || controlMode != ControlMode.Automatic)
+			{
+				points[i] = pointPos;
+
+				if (controlMode == ControlMode.Automatic)
+				{
+					AutoSetAllAffectedControlPoints(i);
+				}
+				else
+				{
+					// Move control points with anchor point
+					if (isAnchorPoint)
+					{
+						if (i + 1 < points.Count || isClosed)
+						{
+							points[LoopIndex(i + 1)] += deltaMove;
+						}
+						if (i - 1 >= 0 || isClosed)
+						{
+							points[LoopIndex(i - 1)] += deltaMove;
+						}
+					}
+					// If not in free control mode, then move attached control point to be aligned/mirrored (depending on mode)
+					else if (controlMode != ControlMode.Free)
+					{
+						bool nextPointIsAnchor = (i + 1) % 3 == 0;
+						int attachedControlIndex = (nextPointIsAnchor) ? i + 2 : i - 2;
+						int anchorIndex = (nextPointIsAnchor) ? i + 1 : i - 1;
+
+						if (attachedControlIndex >= 0 && attachedControlIndex < points.Count || isClosed)
+						{
+							float distanceFromAnchor = 0;
+							// If in aligned mode, then attached control's current distance from anchor point should be maintained
+							if (controlMode == ControlMode.Aligned)
+							{
+								distanceFromAnchor = (points[LoopIndex(anchorIndex)] - points[LoopIndex(attachedControlIndex)]).magnitude;
+							}
+							// If in mirrored mode, then both control points should have the same distance from the anchor point
+							else if (controlMode == ControlMode.Mirrored)
+							{
+								distanceFromAnchor = (points[LoopIndex(anchorIndex)] - points[i]).magnitude;
+
+							}
+							Vector3 dir = (points[LoopIndex(anchorIndex)] - pointPos).normalized;
+							points[LoopIndex(attachedControlIndex)] = points[LoopIndex(anchorIndex)] + dir * distanceFromAnchor;
+						}
+					}
+				}
+
+				if (!suppressPathModifiedEvent)
+				{
+					NotifyPathModified();
+				}
+			}
+		}
+
+		/// Update the bounding box of the path
+		public Bounds CalculateBoundsWithTransform(Transform transform)
+		{
+			// Loop through all segments and keep track of the minmax points of all their bounding boxes
+			MinMax3D minMax = new MinMax3D();
+
+			for (int i = 0; i < NumSegments; i++)
+			{
+				Vector3[] p = GetPointsInSegment(i);
+				for (int j = 0; j < p.Length; j++)
+				{
+					p[j] = MathUtility.TransformPoint(p[j], transform, space);
+				}
+
+				minMax.AddValue(p[0]);
+				minMax.AddValue(p[3]);
+
+				List<float> extremePointTimes = CubicBezierUtility.ExtremePointTimes(p[0], p[1], p[2], p[3]);
+				foreach (float t in extremePointTimes)
+				{
+					minMax.AddValue(CubicBezierUtility.EvaluateCurve(p, t));
+				}
+			}
+
+			return new Bounds((minMax.Min + minMax.Max) / 2, minMax.Max - minMax.Min);
+		}
+
+		/// Flip the normal vectors 180 degrees
+		public bool FlipNormals
+		{
+			get
+			{
+				return flipNormals;
+			}
+			set
+			{
+				if (flipNormals != value)
+				{
+					flipNormals = value;
+					NotifyPathModified();
+				}
+			}
+		}
+
+		/// Global angle that all normal vectors are rotated by (only relevant for paths in 3D space)
+		public float GlobalNormalsAngle
+		{
+			get
+			{
+				return globalNormalsAngle;
+			}
+			set
+			{
+				if (value != globalNormalsAngle)
+				{
+					globalNormalsAngle = value;
+					NotifyPathModified();
+				}
+			}
+		}
+
+		/// Get the desired angle of the normal vector at a particular anchor (only relevant for paths in 3D space)
+		public float GetAnchorNormalAngle(int anchorIndex)
+		{
+			return perAnchorNormalsAngle[anchorIndex] % 360;
+		}
+
+		/// Set the desired angle of the normal vector at a particular anchor (only relevant for paths in 3D space)
+		public void SetAnchorNormalAngle(int anchorIndex, float angle)
+		{
+			angle = (angle + 360) % 360;
+			if (perAnchorNormalsAngle[anchorIndex] != angle)
+			{
+				perAnchorNormalsAngle[anchorIndex] = angle;
+				NotifyPathModified();
+			}
+		}
+
+		/// Reset global and anchor normal angles to 0
+		public void ResetNormalAngles()
+		{
+			for (int i = 0; i < perAnchorNormalsAngle.Count; i++)
+			{
+				perAnchorNormalsAngle[i] = 0;
+			}
+			globalNormalsAngle = 0;
+			NotifyPathModified();
+		}
+
+		/// Bounding box containing the path
+		public Bounds PathBounds
+		{
+			get
+			{
+				if (!boundsUpToDate)
+				{
+					UpdateBounds();
+				}
+				return bounds;
+			}
+		}
+
+		#endregion
+
+		#region Internal methods and accessors
+
+		/// Update the bounding box of the path
+		void UpdateBounds()
+		{
+			if (boundsUpToDate)
+			{
+				return;
+			}
+
+			// Loop through all segments and keep track of the minmax points of all their bounding boxes
+			MinMax3D minMax = new MinMax3D();
+
+			for (int i = 0; i < NumSegments; i++)
+			{
+				Vector3[] p = GetPointsInSegment(i);
+				minMax.AddValue(p[0]);
+				minMax.AddValue(p[3]);
+
+				List<float> extremePointTimes = CubicBezierUtility.ExtremePointTimes(p[0], p[1], p[2], p[3]);
+				foreach (float t in extremePointTimes)
+				{
+					minMax.AddValue(CubicBezierUtility.EvaluateCurve(p, t));
+				}
+			}
+
+			boundsUpToDate = true;
+			bounds = new Bounds((minMax.Min + minMax.Max) / 2, minMax.Max - minMax.Min);
+		}
+
+		/// Determines good positions (for a smooth path) for the control points affected by a moved/inserted anchor point
+		void AutoSetAllAffectedControlPoints(int updatedAnchorIndex)
+		{
+			for (int i = updatedAnchorIndex - 3; i <= updatedAnchorIndex + 3; i += 3)
+			{
+				if (i >= 0 && i < points.Count || isClosed)
+				{
+					AutoSetAnchorControlPoints(LoopIndex(i));
+				}
+			}
+
+			AutoSetStartAndEndControls();
+		}
+
+		/// Determines good positions (for a smooth path) for all control points
+		void AutoSetAllControlPoints()
+		{
+			if (NumAnchorPoints > 2)
+			{
+				for (int i = 0; i < points.Count; i += 3)
+				{
+					AutoSetAnchorControlPoints(i);
+				}
+			}
+
+			AutoSetStartAndEndControls();
+		}
+
+		/// Calculates good positions (to result in smooth path) for the controls around specified anchor
+		void AutoSetAnchorControlPoints(int anchorIndex)
+		{
+			// Calculate a vector that is perpendicular to the vector bisecting the angle between this anchor and its two immediate neighbours
+			// The control points will be placed along that vector
+			Vector3 anchorPos = points[anchorIndex];
+			Vector3 dir = Vector3.zero;
+			float[] neighbourDistances = new float[2];
+
+			if (anchorIndex - 3 >= 0 || isClosed)
+			{
+				Vector3 offset = points[LoopIndex(anchorIndex - 3)] - anchorPos;
+				dir += offset.normalized;
+				neighbourDistances[0] = offset.magnitude;
+			}
+			if (anchorIndex + 3 >= 0 || isClosed)
+			{
+				Vector3 offset = points[LoopIndex(anchorIndex + 3)] - anchorPos;
+				dir -= offset.normalized;
+				neighbourDistances[1] = -offset.magnitude;
+			}
+
+			dir.Normalize();
+
+			// Set the control points along the calculated direction, with a distance proportional to the distance to the neighbouring control point
+			for (int i = 0; i < 2; i++)
+			{
+				int controlIndex = anchorIndex + i * 2 - 1;
+				if (controlIndex >= 0 && controlIndex < points.Count || isClosed)
+				{
+					points[LoopIndex(controlIndex)] = anchorPos + dir * neighbourDistances[i] * autoControlLength;
+				}
+			}
+		}
+
+		/// Determines good positions (for a smooth path) for the control points at the start and end of a path
+		void AutoSetStartAndEndControls()
+		{
+			if (isClosed)
+			{
+				// Handle case with only 2 anchor points separately, as will otherwise result in straight line ()
+				if (NumAnchorPoints == 2)
+				{
+					Vector3 dirAnchorAToB = (points[3] - points[0]).normalized;
+					float dstBetweenAnchors = (points[0] - points[3]).magnitude;
+					Vector3 perp = Vector3.Cross(dirAnchorAToB, (space == PathSpace.xy) ? Vector3.forward : Vector3.up);
+					points[1] = points[0] + perp * dstBetweenAnchors / 2f;
+					points[5] = points[0] - perp * dstBetweenAnchors / 2f;
+					points[2] = points[3] + perp * dstBetweenAnchors / 2f;
+					points[4] = points[3] - perp * dstBetweenAnchors / 2f;
+
+				}
+				else
+				{
+					AutoSetAnchorControlPoints(0);
+					AutoSetAnchorControlPoints(points.Count - 3);
+				}
+			}
+			else
+			{
+				// Handle case with 2 anchor points separately, as otherwise minor adjustments cause path to constantly flip
+				if (NumAnchorPoints == 2)
+				{
+					points[1] = points[0] + (points[3] - points[0]) * .25f;
+					points[2] = points[3] + (points[0] - points[3]) * .25f;
+				}
+				else
+				{
+					points[1] = (points[0] + points[2]) * .5f;
+					points[points.Count - 2] = (points[points.Count - 1] + points[points.Count - 3]) * .5f;
+				}
+			}
+		}
+
+		/// Update point positions for new path space
+		/// (for example, if changing from xy to xz path, y and z axes will be swapped so the path keeps its shape in the new space)
+		void UpdateToNewPathSpace(PathSpace previousSpace)
+		{
+			// If changing from 3d to 2d space, first find the bounds of the 3d path.
+			// The axis with the smallest bounds will be discarded.
+			if (previousSpace == PathSpace.xyz)
+			{
+				Vector3 boundsSize = PathBounds.size;
+				float minBoundsSize = Mathf.Min(boundsSize.x, boundsSize.y, boundsSize.z);
+
+				for (int i = 0; i < NumPoints; i++)
+				{
+					if (space == PathSpace.xy)
+					{
+						float x = (minBoundsSize == boundsSize.x) ? points[i].z : points[i].x;
+						float y = (minBoundsSize == boundsSize.y) ? points[i].z : points[i].y;
+						points[i] = new Vector3(x, y, 0);
+					}
+					else if (space == PathSpace.xz)
+					{
+						float x = (minBoundsSize == boundsSize.x) ? points[i].y : points[i].x;
+						float z = (minBoundsSize == boundsSize.z) ? points[i].y : points[i].z;
+						points[i] = new Vector3(x, 0, z);
+					}
+				}
+			}
+			else
+			{
+				// Nothing needs to change when going to 3d space
+				if (space != PathSpace.xyz)
+				{
+					for (int i = 0; i < NumPoints; i++)
+					{
+						// from xz to xy
+						if (space == PathSpace.xy)
+						{
+							points[i] = new Vector3(points[i].x, points[i].z, 0);
+						}
+						// from xy to xz
+						else if (space == PathSpace.xz)
+						{
+							points[i] = new Vector3(points[i].x, 0, points[i].y);
+						}
+					}
+				}
+			}
+
+			NotifyPathModified();
+		}
+
+		/// Add/remove the extra 2 controls required for a closed path
+		void UpdateClosedState()
+		{
+			if (isClosed)
+			{
+				// Set positions for new controls to mirror their counterparts
+				Vector3 lastAnchorSecondControl = points[points.Count - 1] * 2 - points[points.Count - 2];
+				Vector3 firstAnchorSecondControl = points[0] * 2 - points[1];
+				if (controlMode != ControlMode.Mirrored && controlMode != ControlMode.Automatic)
+				{
+					// Set positions for new controls to be aligned with their counterparts, but with a length of half the distance between start/end anchor
+					float dstBetweenStartAndEndAnchors = (points[points.Count - 1] - points[0]).magnitude;
+					lastAnchorSecondControl = points[points.Count - 1] + (points[points.Count - 1] - points[points.Count - 2]).normalized * dstBetweenStartAndEndAnchors * .5f;
+					firstAnchorSecondControl = points[0] + (points[0] - points[1]).normalized * dstBetweenStartAndEndAnchors * .5f;
+				}
+				points.Add(lastAnchorSecondControl);
+				points.Add(firstAnchorSecondControl);
+			}
+			else
+			{
+				points.RemoveRange(points.Count - 2, 2);
+
+			}
+
+			if (controlMode == ControlMode.Automatic)
+			{
+				AutoSetStartAndEndControls();
+			}
+
+			if (OnModified != null)
+			{
+				OnModified();
+			}
+		}
+
+		/// Loop index around to start/end of points array if out of bounds (useful when working with closed paths)
+		int LoopIndex(int i)
+		{
+			return (i + points.Count) % points.Count;
+		}
+
+		// Called when the path is modified
+		public void NotifyPathModified()
+		{
+			boundsUpToDate = false;
+			if (OnModified != null)
+			{
+				OnModified();
+			}
+		}
+
+		#endregion
+
+	}
+}

+ 13 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/BezierPath.cs.meta

@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: 756209f371f304fb1920c53a8a25a5e2
+timeCreated: 1516786483
+licenseType: Pro
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/EndOfPathInstruction.cs

@@ -0,0 +1,3 @@
+namespace PathCreation {
+	public enum EndOfPathInstruction {Loop, Reverse, Stop};
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/EndOfPathInstruction.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c0d7fa70c03166e4180909b6e5d546c7
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 70 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/GlobalDisplaySettings.cs

@@ -0,0 +1,70 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace PathCreation
+{
+    //[CreateAssetMenu()]
+    public class GlobalDisplaySettings : ScriptableObject
+    {
+
+        public enum HandleType { Sphere, Circle, Square };
+
+        [Header("Appearance")]
+        public float anchorSize = 10;
+        public float controlSize = 7f;
+        
+        [Tooltip("Should the path still be drawn when behind objects in the scene?")]
+        public bool visibleBehindObjects = true;
+        [Tooltip("Should the path be drawn even when the path object is not selected?")]
+        public bool visibleWhenNotSelected = true;
+        [Tooltip("If true, control points will be hidden when the control point mode is set to automatic. Otherwise they will inactive, but still visible.")]
+        public bool hideAutoControls = true;
+        public HandleType anchorShape;
+        public HandleType controlShape;
+
+
+        [Header("Anchor Colours")]
+        public Color anchor = new Color(0.95f, 0.25f, 0.25f, 0.85f);
+        public Color anchorHighlighted = new Color(1, 0.57f, 0.4f);
+        public Color anchorSelected = Color.white;
+
+        [Header("Control Colours")]
+        public Color control = new Color(0.35f, 0.6f, 1, 0.85f);
+        public Color controlHighlighted = new Color(0.8f, 0.67f, 0.97f);
+        public Color controlSelected = Color.white;
+        public Color handleDisabled = new Color(1, 1, 1, 0.2f);
+        public Color controlLine = new Color(0, 0, 0, 0.35f);
+
+        [Header("Bezier Path Colours")]
+        public Color bezierPath = Color.green;
+        public Color highlightedPath = new Color(1, 0.6f, 0);
+        public Color bounds = new Color(1, 1, 1, .4f);
+        public Color segmentBounds = new Color(1, 1, 1, .4f);
+
+        [Header("Vertex Path Colours")]
+        public Color vertexPath = Color.white;
+
+        [Header("Normals")]
+        public Color normals = Color.yellow;
+        [Range(0,1)]
+        public float normalsLength = .1f;
+
+#if UNITY_EDITOR
+        public static GlobalDisplaySettings Load() {
+            string[] guids = UnityEditor.AssetDatabase.FindAssets("t:GlobalDisplaySettings");
+            if (guids.Length == 0)
+            {
+                Debug.LogWarning("Could not find DisplaySettings asset. Will use default settings instead.");
+                return ScriptableObject.CreateInstance<GlobalDisplaySettings>();
+            }
+            else
+            {
+                string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guids[0]);
+                return UnityEditor.AssetDatabase.LoadAssetAtPath<GlobalDisplaySettings>(path);
+            }
+        }
+#endif
+
+    }
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/GlobalDisplaySettings.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 46d5e8d803e252f4499b52e657f8e1a2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 21 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/MinMax3D.cs

@@ -0,0 +1,21 @@
+using UnityEngine;
+
+namespace PathCreation {
+    public class MinMax3D {
+
+        public Vector3 Min { get; private set; }
+        public Vector3 Max { get; private set; }
+
+        public MinMax3D()
+        {
+            Min = Vector3.one * float.MaxValue;
+            Max = Vector3.one * float.MinValue;
+        }
+
+        public void AddValue(Vector3 v)
+        {
+            Min = new Vector3(Mathf.Min(Min.x, v.x), Mathf.Min(Min.y,v.y), Mathf.Min(Min.z,v.z));
+            Max = new Vector3(Mathf.Max(Max.x, v.x), Mathf.Max(Max.y,v.y), Mathf.Max(Max.z,v.z));
+        }
+    }
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/MinMax3D.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 194e1b7893dcbf940a71eb507d8b10f3
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 112 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathCreator.cs

@@ -0,0 +1,112 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace PathCreation {
+    public class PathCreator : MonoBehaviour {
+
+        /// This class stores data for the path editor, and provides accessors to get the current vertex and bezier path.
+        /// Attach to a GameObject to create a new path editor.
+
+        public event System.Action pathUpdated;
+
+        [SerializeField, HideInInspector]
+        PathCreatorData editorData;
+        [SerializeField, HideInInspector]
+        bool initialized;
+
+        GlobalDisplaySettings globalEditorDisplaySettings;
+
+        // Vertex path created from the current bezier path
+        public VertexPath path {
+            get {
+                if (!initialized) {
+                    InitializeEditorData (false);
+                }
+                return editorData.GetVertexPath(transform);
+            }
+        }
+
+        // The bezier path created in the editor
+        public BezierPath bezierPath {
+            get {
+                if (!initialized) {
+                    InitializeEditorData (false);
+                }
+                return editorData.bezierPath;
+            }
+            set {
+                if (!initialized) {
+                    InitializeEditorData (false);
+                }
+                editorData.bezierPath = value;
+            }
+        }
+
+        #region Internal methods
+
+        /// Used by the path editor to initialise some data
+        public void InitializeEditorData (bool in2DMode) {
+            if (editorData == null) {
+                editorData = new PathCreatorData ();
+            }
+            editorData.bezierOrVertexPathModified -= TriggerPathUpdate;
+            editorData.bezierOrVertexPathModified += TriggerPathUpdate;
+
+            editorData.Initialize (in2DMode);
+            initialized = true;
+        }
+
+        public PathCreatorData EditorData {
+            get {
+                return editorData;
+            }
+
+        }
+
+        public void TriggerPathUpdate () {
+            if (pathUpdated != null) {
+                pathUpdated ();
+            }
+        }
+
+#if UNITY_EDITOR
+
+        // Draw the path when path objected is not selected (if enabled in settings)
+        void OnDrawGizmos () {
+
+            // Only draw path gizmo if the path object is not selected
+            // (editor script is resposible for drawing when selected)
+            GameObject selectedObj = UnityEditor.Selection.activeGameObject;
+            if (selectedObj != gameObject) {
+
+                if (path != null) {
+                    path.UpdateTransform (transform);
+
+                    if (globalEditorDisplaySettings == null) {
+                        globalEditorDisplaySettings = GlobalDisplaySettings.Load ();
+                    }
+
+                    if (globalEditorDisplaySettings.visibleWhenNotSelected) {
+
+                        Gizmos.color = globalEditorDisplaySettings.bezierPath;
+
+                        for (int i = 0; i < path.NumPoints; i++) {
+                            int nextI = i + 1;
+                            if (nextI >= path.NumPoints) {
+                                if (path.isClosedLoop) {
+                                    nextI %= path.NumPoints;
+                                } else {
+                                    break;
+                                }
+                            }
+                            Gizmos.DrawLine (path.GetPoint (i), path.GetPoint (nextI));
+                        }
+                    }
+                }
+            }
+        }
+#endif
+
+        #endregion
+    }
+}

+ 13 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathCreator.cs.meta

@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: 8e5ac92bc18f545cc84cd886ece82b4d
+timeCreated: 1516864223
+licenseType: Pro
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 136 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathCreatorData.cs

@@ -0,0 +1,136 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace PathCreation {
+    /// Stores state data for the path creator editor
+
+    [System.Serializable]
+    public class PathCreatorData {
+        public event System.Action bezierOrVertexPathModified;
+        public event System.Action bezierCreated;
+
+        [SerializeField]
+        BezierPath _bezierPath;
+        VertexPath _vertexPath;
+
+        [SerializeField]
+        bool vertexPathUpToDate;
+
+        // vertex path settings
+        public float vertexPathMaxAngleError = .3f;
+        public float vertexPathMinVertexSpacing = 0.01f;
+
+        // bezier display settings
+        public bool showTransformTool = true;
+        public bool showPathBounds;
+        public bool showPerSegmentBounds;
+        public bool displayAnchorPoints = true;
+        public bool displayControlPoints = true;
+        public float bezierHandleScale = 1;
+        public bool globalDisplaySettingsFoldout;
+        public bool keepConstantHandleSize;
+
+        // vertex display settings
+        public bool showNormalsInVertexMode;
+        public bool showBezierPathInVertexMode;
+
+        // Editor display states
+        public bool showDisplayOptions;
+        public bool showPathOptions = true;
+        public bool showVertexPathDisplayOptions;
+        public bool showVertexPathOptions = true;
+        public bool showNormals;
+        public bool showNormalsHelpInfo;
+        public int tabIndex;
+
+        public void Initialize (bool defaultIs2D) {
+            if (_bezierPath == null) {
+                CreateBezier (Vector3.zero, defaultIs2D);
+            }
+            vertexPathUpToDate = false;
+            _bezierPath.OnModified -= BezierPathEdited;
+            _bezierPath.OnModified += BezierPathEdited;
+        }
+
+        public void ResetBezierPath (Vector3 centre, bool defaultIs2D = false) {
+            CreateBezier (centre, defaultIs2D);
+        }
+
+        void CreateBezier (Vector3 centre, bool defaultIs2D = false) {
+            if (_bezierPath != null) {
+                _bezierPath.OnModified -= BezierPathEdited;
+            }
+
+            var space = (defaultIs2D) ? PathSpace.xy : PathSpace.xyz;
+            _bezierPath = new BezierPath (centre, false, space);
+
+            _bezierPath.OnModified += BezierPathEdited;
+            vertexPathUpToDate = false;
+
+            if (bezierOrVertexPathModified != null) {
+                bezierOrVertexPathModified ();
+            }
+            if (bezierCreated != null) {
+                bezierCreated ();
+            }
+        }
+
+        public BezierPath bezierPath {
+            get {
+                return _bezierPath;
+            }
+            set {
+                _bezierPath.OnModified -= BezierPathEdited;
+                vertexPathUpToDate = false;
+                _bezierPath = value;
+                _bezierPath.OnModified += BezierPathEdited;
+
+                if (bezierOrVertexPathModified != null) {
+                    bezierOrVertexPathModified ();
+                }
+                if (bezierCreated != null) {
+                    bezierCreated ();
+                }
+
+            }
+        }
+
+        // Get the current vertex path
+        public VertexPath GetVertexPath (Transform transform) {
+            // create new vertex path if path was modified since this vertex path was created
+            if (!vertexPathUpToDate || _vertexPath == null) {
+                vertexPathUpToDate = true;
+                _vertexPath = new VertexPath (bezierPath, transform, vertexPathMaxAngleError, vertexPathMinVertexSpacing);
+            }
+            return _vertexPath;
+        }
+
+        public void PathTransformed () {
+            if (bezierOrVertexPathModified != null) {
+                bezierOrVertexPathModified ();
+            }
+        }
+
+        public void VertexPathSettingsChanged () {
+            vertexPathUpToDate = false;
+            if (bezierOrVertexPathModified != null) {
+                bezierOrVertexPathModified ();
+            }
+        }
+
+        public void PathModifiedByUndo () {
+            vertexPathUpToDate = false;
+            if (bezierOrVertexPathModified != null) {
+                bezierOrVertexPathModified ();
+            }
+        }
+
+        void BezierPathEdited () {
+            vertexPathUpToDate = false;
+            if (bezierOrVertexPathModified != null) {
+                bezierOrVertexPathModified ();
+            }
+        }
+
+    }
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathCreatorData.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 19547029ffb83484e90d00c182104817
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathSpace.cs

@@ -0,0 +1,3 @@
+namespace PathCreation {
+	public enum PathSpace {xyz, xy, xz};
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/PathSpace.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 407af8f85a5bae449bce4730c5d97d1a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 355 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/VertexPath.cs

@@ -0,0 +1,355 @@
+using System.Collections.Generic;
+using PathCreation.Utility;
+using UnityEngine;
+
+
+namespace PathCreation {
+    /// A vertex path is a collection of points (vertices) that lie along a bezier path.
+    /// This allows one to do things like move at a constant speed along the path,
+    /// which is not possible with a bezier path directly due to how they're constructed mathematically.
+
+    /// This class also provides methods for getting the position along the path at a certain distance or time
+    /// (where time = 0 is the start of the path, and time = 1 is the end of the path).
+    /// Other info about the path (tangents, normals, rotation) can also be retrieved in this manner.
+
+    public class VertexPath {
+        #region Fields
+
+        public readonly PathSpace space;
+        public readonly bool isClosedLoop;
+        public readonly Vector3[] localPoints;
+        public readonly Vector3[] localTangents;
+        public readonly Vector3[] localNormals;
+
+        /// Percentage along the path at each vertex (0 being start of path, and 1 being the end)
+        public readonly float[] times;
+        /// Total distance between the vertices of the polyline
+        public readonly float length;
+        /// Total distance from the first vertex up to each vertex in the polyline
+        public readonly float[] cumulativeLengthAtEachVertex;
+        /// Bounding box of the path
+        public readonly Bounds bounds;
+        /// Equal to (0,0,-1) for 2D paths, and (0,1,0) for XZ paths
+        public readonly Vector3 up;
+
+        // Default values and constants:
+        const int accuracy = 10; // A scalar for how many times bezier path is divided when determining vertex positions
+        const float minVertexSpacing = .01f;
+
+        Transform transform;
+
+        #endregion
+
+        #region Constructors
+
+        /// <summary> Splits bezier path into array of vertices along the path.</summary>
+        ///<param name="maxAngleError">How much can the angle of the path change before a vertex is added. This allows fewer vertices to be generated in straighter sections.</param>
+        ///<param name="minVertexDst">Vertices won't be added closer together than this distance, regardless of angle error.</param>
+        public VertexPath (BezierPath bezierPath, Transform transform, float maxAngleError = 0.3f, float minVertexDst = 0):
+            this (bezierPath, VertexPathUtility.SplitBezierPathByAngleError (bezierPath, maxAngleError, minVertexDst, VertexPath.accuracy), transform) { }
+
+        /// <summary> Splits bezier path into array of vertices along the path.</summary>
+        ///<param name="maxAngleError">How much can the angle of the path change before a vertex is added. This allows fewer vertices to be generated in straighter sections.</param>
+        ///<param name="minVertexDst">Vertices won't be added closer together than this distance, regardless of angle error.</param>
+        ///<param name="accuracy">Higher value means the change in angle is checked more frequently.</param>
+        public VertexPath (BezierPath bezierPath, Transform transform, float vertexSpacing):
+            this (bezierPath, VertexPathUtility.SplitBezierPathEvenly (bezierPath, Mathf.Max (vertexSpacing, minVertexSpacing), VertexPath.accuracy), transform) { }
+
+        /// Internal contructor
+        VertexPath (BezierPath bezierPath, VertexPathUtility.PathSplitData pathSplitData, Transform transform) {
+            this.transform = transform;
+            space = bezierPath.Space;
+            isClosedLoop = bezierPath.IsClosed;
+            int numVerts = pathSplitData.vertices.Count;
+            length = pathSplitData.cumulativeLength[numVerts - 1];
+
+            localPoints = new Vector3[numVerts];
+            localNormals = new Vector3[numVerts];
+            localTangents = new Vector3[numVerts];
+            cumulativeLengthAtEachVertex = new float[numVerts];
+            times = new float[numVerts];
+            bounds = new Bounds ((pathSplitData.minMax.Min + pathSplitData.minMax.Max) / 2, pathSplitData.minMax.Max - pathSplitData.minMax.Min);
+
+            // Figure out up direction for path
+            up = (bounds.size.z > bounds.size.y) ? Vector3.up : -Vector3.forward;
+            Vector3 lastRotationAxis = up;
+
+            // Loop through the data and assign to arrays.
+            for (int i = 0; i < localPoints.Length; i++) {
+                localPoints[i] = pathSplitData.vertices[i];
+                localTangents[i] = pathSplitData.tangents[i];
+                cumulativeLengthAtEachVertex[i] = pathSplitData.cumulativeLength[i];
+                times[i] = cumulativeLengthAtEachVertex[i] / length;
+
+                // Calculate normals
+                if (space == PathSpace.xyz) {
+                    if (i == 0) {
+                        localNormals[0] = Vector3.Cross (lastRotationAxis, pathSplitData.tangents[0]).normalized;
+                    } else {
+                        // First reflection
+                        Vector3 offset = (localPoints[i] - localPoints[i - 1]);
+                        float sqrDst = offset.sqrMagnitude;
+                        Vector3 r = lastRotationAxis - offset * 2 / sqrDst * Vector3.Dot (offset, lastRotationAxis);
+                        Vector3 t = localTangents[i - 1] - offset * 2 / sqrDst * Vector3.Dot (offset, localTangents[i - 1]);
+
+                        // Second reflection
+                        Vector3 v2 = localTangents[i] - t;
+                        float c2 = Vector3.Dot (v2, v2);
+
+                        Vector3 finalRot = r - v2 * 2 / c2 * Vector3.Dot (v2, r);
+                        Vector3 n = Vector3.Cross (finalRot, localTangents[i]).normalized;
+                        localNormals[i] = n;
+                        lastRotationAxis = finalRot;
+                    }
+                } else {
+                    localNormals[i] = Vector3.Cross (localTangents[i], up) * ((bezierPath.FlipNormals) ? 1 : -1);
+                }
+            }
+
+            // Apply correction for 3d normals along a closed path
+            if (space == PathSpace.xyz && isClosedLoop) {
+                // Get angle between first and last normal (if zero, they're already lined up, otherwise we need to correct)
+                float normalsAngleErrorAcrossJoin = Vector3.SignedAngle (localNormals[localNormals.Length - 1], localNormals[0], localTangents[0]);
+                // Gradually rotate the normals along the path to ensure start and end normals line up correctly
+                if (Mathf.Abs (normalsAngleErrorAcrossJoin) > 0.1f) // don't bother correcting if very nearly correct
+                {
+                    for (int i = 1; i < localNormals.Length; i++) {
+                        float t = (i / (localNormals.Length - 1f));
+                        float angle = normalsAngleErrorAcrossJoin * t;
+                        Quaternion rot = Quaternion.AngleAxis (angle, localTangents[i]);
+                        localNormals[i] = rot * localNormals[i] * ((bezierPath.FlipNormals) ? -1 : 1);
+                    }
+                }
+            }
+
+            // Rotate normals to match up with user-defined anchor angles
+            if (space == PathSpace.xyz) {
+                for (int anchorIndex = 0; anchorIndex < pathSplitData.anchorVertexMap.Count - 1; anchorIndex++) {
+                    int nextAnchorIndex = (isClosedLoop) ? (anchorIndex + 1) % bezierPath.NumSegments : anchorIndex + 1;
+
+                    float startAngle = bezierPath.GetAnchorNormalAngle (anchorIndex) + bezierPath.GlobalNormalsAngle;
+                    float endAngle = bezierPath.GetAnchorNormalAngle (nextAnchorIndex) + bezierPath.GlobalNormalsAngle;
+                    float deltaAngle = Mathf.DeltaAngle (startAngle, endAngle);
+
+                    int startVertIndex = pathSplitData.anchorVertexMap[anchorIndex];
+                    int endVertIndex = pathSplitData.anchorVertexMap[anchorIndex + 1];
+
+                    int num = endVertIndex - startVertIndex;
+                    if (anchorIndex == pathSplitData.anchorVertexMap.Count - 2) {
+                        num += 1;
+                    }
+                    for (int i = 0; i < num; i++) {
+                        int vertIndex = startVertIndex + i;
+                        float t = num == 1 ? 1f : i / (num - 1f);
+                        float angle = startAngle + deltaAngle * t;
+                        Quaternion rot = Quaternion.AngleAxis (angle, localTangents[vertIndex]);
+                        localNormals[vertIndex] = (rot * localNormals[vertIndex]) * ((bezierPath.FlipNormals) ? -1 : 1);
+                    }
+                }
+            }
+        }
+
+        #endregion
+
+        #region Public methods and accessors
+
+        public void UpdateTransform (Transform transform) {
+            this.transform = transform;
+        }
+        public int NumPoints {
+            get {
+                return localPoints.Length;
+            }
+        }
+
+        public Vector3 GetTangent (int index) {
+            return MathUtility.TransformDirection (localTangents[index], transform, space);
+        }
+
+        public Vector3 GetNormal (int index) {
+            return MathUtility.TransformDirection (localNormals[index], transform, space);
+        }
+
+        public Vector3 GetPoint (int index) {
+            return MathUtility.TransformPoint (localPoints[index], transform, space);
+        }
+
+        /// Gets point on path based on distance travelled.
+        public Vector3 GetPointAtDistance (float dst, EndOfPathInstruction endOfPathInstruction = EndOfPathInstruction.Loop) {
+            float t = dst / length;
+            return GetPointAtTime (t, endOfPathInstruction);
+        }
+
+        /// Gets forward direction on path based on distance travelled.
+        public Vector3 GetDirectionAtDistance (float dst, EndOfPathInstruction endOfPathInstruction = EndOfPathInstruction.Loop) {
+            float t = dst / length;
+            return GetDirection (t, endOfPathInstruction);
+        }
+
+        /// Gets normal vector on path based on distance travelled.
+        public Vector3 GetNormalAtDistance (float dst, EndOfPathInstruction endOfPathInstruction = EndOfPathInstruction.Loop) {
+            float t = dst / length;
+            return GetNormal (t, endOfPathInstruction);
+        }
+
+        /// Gets a rotation that will orient an object in the direction of the path at this point, with local up point along the path's normal
+        public Quaternion GetRotationAtDistance (float dst, EndOfPathInstruction endOfPathInstruction = EndOfPathInstruction.Loop) {
+            float t = dst / length;
+            return GetRotation (t, endOfPathInstruction);
+        }
+
+        /// Gets point on path based on 'time' (where 0 is start, and 1 is end of path).
+        public Vector3 GetPointAtTime (float t, EndOfPathInstruction endOfPathInstruction = EndOfPathInstruction.Loop) {
+            var data = CalculatePercentOnPathData (t, endOfPathInstruction);
+            return Vector3.Lerp (GetPoint (data.previousIndex), GetPoint (data.nextIndex), data.percentBetweenIndices);
+        }
+
+        /// Gets forward direction on path based on 'time' (where 0 is start, and 1 is end of path).
+        public Vector3 GetDirection (float t, EndOfPathInstruction endOfPathInstruction = EndOfPathInstruction.Loop) {
+            var data = CalculatePercentOnPathData (t, endOfPathInstruction);
+            Vector3 dir = Vector3.Lerp (localTangents[data.previousIndex], localTangents[data.nextIndex], data.percentBetweenIndices);
+            return MathUtility.TransformDirection (dir, transform, space);
+        }
+
+        /// Gets normal vector on path based on 'time' (where 0 is start, and 1 is end of path).
+        public Vector3 GetNormal (float t, EndOfPathInstruction endOfPathInstruction = EndOfPathInstruction.Loop) {
+            var data = CalculatePercentOnPathData (t, endOfPathInstruction);
+            Vector3 normal = Vector3.Lerp (localNormals[data.previousIndex], localNormals[data.nextIndex], data.percentBetweenIndices);
+            return MathUtility.TransformDirection (normal, transform, space);
+        }
+
+        /// Gets a rotation that will orient an object in the direction of the path at this point, with local up point along the path's normal
+        public Quaternion GetRotation (float t, EndOfPathInstruction endOfPathInstruction = EndOfPathInstruction.Loop) {
+            var data = CalculatePercentOnPathData (t, endOfPathInstruction);
+            Vector3 direction = Vector3.Lerp (localTangents[data.previousIndex], localTangents[data.nextIndex], data.percentBetweenIndices);
+            Vector3 normal = Vector3.Lerp (localNormals[data.previousIndex], localNormals[data.nextIndex], data.percentBetweenIndices);
+            return Quaternion.LookRotation (MathUtility.TransformDirection (direction, transform, space), MathUtility.TransformDirection (normal, transform, space));
+        }
+
+        /// Finds the closest point on the path from any point in the world
+        public Vector3 GetClosestPointOnPath (Vector3 worldPoint) {
+            // Transform the provided worldPoint into VertexPath local-space.
+            // This allows to do math on the localPoint's, thus avoiding the need to
+            // transform each local vertexpath point into world space via GetPoint.
+            Vector3 localPoint = MathUtility.InverseTransformPoint(worldPoint, transform, space);
+
+            TimeOnPathData data = CalculateClosestPointOnPathData (localPoint);
+            Vector3 localResult = Vector3.Lerp (localPoints[data.previousIndex], localPoints[data.nextIndex], data.percentBetweenIndices);
+
+            // Transform local result into world space
+            return MathUtility.TransformPoint(localResult, transform, space);
+        }
+
+        /// Finds the 'time' (0=start of path, 1=end of path) along the path that is closest to the given point
+        public float GetClosestTimeOnPath (Vector3 worldPoint) {
+            Vector3 localPoint = MathUtility.InverseTransformPoint(worldPoint, transform, space);
+            TimeOnPathData data = CalculateClosestPointOnPathData (localPoint);
+            return Mathf.Lerp (times[data.previousIndex], times[data.nextIndex], data.percentBetweenIndices);
+        }
+
+        /// Finds the distance along the path that is closest to the given point
+        public float GetClosestDistanceAlongPath (Vector3 worldPoint) {
+            Vector3 localPoint = MathUtility.InverseTransformPoint(worldPoint, transform, space);
+            TimeOnPathData data = CalculateClosestPointOnPathData(localPoint);
+            return Mathf.Lerp (cumulativeLengthAtEachVertex[data.previousIndex], cumulativeLengthAtEachVertex[data.nextIndex], data.percentBetweenIndices);
+        }
+
+        #endregion
+
+        #region Internal methods
+
+        /// For a given value 't' between 0 and 1, calculate the indices of the two vertices before and after t.
+        /// Also calculate how far t is between those two vertices as a percentage between 0 and 1.
+        TimeOnPathData CalculatePercentOnPathData (float t, EndOfPathInstruction endOfPathInstruction) {
+            // Constrain t based on the end of path instruction
+            switch (endOfPathInstruction) {
+                case EndOfPathInstruction.Loop:
+                    // If t is negative, make it the equivalent value between 0 and 1
+                    if (t < 0) {
+                        t += Mathf.CeilToInt (Mathf.Abs (t));
+                    }
+                    t %= 1;
+                    break;
+                case EndOfPathInstruction.Reverse:
+                    t = Mathf.PingPong (t, 1);
+                    break;
+                case EndOfPathInstruction.Stop:
+                    t = Mathf.Clamp01 (t);
+                    break;
+            }
+
+            int prevIndex = 0;
+            int nextIndex = NumPoints - 1;
+            int i = Mathf.RoundToInt (t * (NumPoints - 1)); // starting guess
+
+            // Starts by looking at middle vertex and determines if t lies to the left or to the right of that vertex.
+            // Continues dividing in half until closest surrounding vertices have been found.
+            while (true) {
+                // t lies to left
+                if (t <= times[i]) {
+                    nextIndex = i;
+                }
+                // t lies to right
+                else {
+                    prevIndex = i;
+                }
+                i = (nextIndex + prevIndex) / 2;
+
+                if (nextIndex - prevIndex <= 1) {
+                    break;
+                }
+            }
+
+            float abPercent = Mathf.InverseLerp (times[prevIndex], times[nextIndex], t);
+            return new TimeOnPathData (prevIndex, nextIndex, abPercent);
+        }
+
+        /// Calculate time data for closest point on the path from given world point
+        TimeOnPathData CalculateClosestPointOnPathData (Vector3 localPoint) {
+            float minSqrDst = float.MaxValue;
+            Vector3 closestPoint = Vector3.zero;
+            int closestSegmentIndexA = 0;
+            int closestSegmentIndexB = 0;
+
+            for (int i = 0; i < localPoints.Length; i++) {
+                int nextI = i + 1;
+                if (nextI >= localPoints.Length) {
+                    if (isClosedLoop) {
+                        nextI %= localPoints.Length;
+                    } else {
+                        break;
+                    }
+                }
+
+                Vector3 closestPointOnSegment = MathUtility.ClosestPointOnLineSegment (localPoint, localPoints[i], localPoints[nextI]);
+                float sqrDst = (localPoint - closestPointOnSegment).sqrMagnitude;
+                if (sqrDst < minSqrDst) {
+                    minSqrDst = sqrDst;
+                    closestPoint = closestPointOnSegment;
+                    closestSegmentIndexA = i;
+                    closestSegmentIndexB = nextI;
+                }
+
+            }
+            float closestSegmentLength = (localPoints[closestSegmentIndexA] - localPoints[closestSegmentIndexB]).magnitude;
+            float t = (closestPoint - localPoints[closestSegmentIndexA]).magnitude / closestSegmentLength;
+            return new TimeOnPathData (closestSegmentIndexA, closestSegmentIndexB, t);
+        }
+
+        public struct TimeOnPathData {
+            public readonly int previousIndex;
+            public readonly int nextIndex;
+            public readonly float percentBetweenIndices;
+
+            public TimeOnPathData (int prev, int next, float percentBetweenIndices) {
+                this.previousIndex = prev;
+                this.nextIndex = next;
+                this.percentBetweenIndices = percentBetweenIndices;
+            }
+        }
+
+        #endregion
+
+    }
+
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Objects/VertexPath.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 223183313f20d4049a397d83fab3151e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/PathCreator.asmdef

@@ -0,0 +1,3 @@
+{
+	"name": "PathCreator"
+}

+ 7 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/PathCreator.asmdef.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 626070ea3273cb844a310aa4f53b31fa
+AssemblyDefinitionImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4c55bdfe2cdafc04ba5f909d4f1f192b
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 136 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/CubicBezierUtility.cs

@@ -0,0 +1,136 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace PathCreation.Utility {
+
+    /// Collection of functions related to cubic bezier curves
+    /// (a curve with a start and end 'anchor' point, and two 'control' points to define the shape of the curve between the anchors)
+    public static class CubicBezierUtility {
+
+        /// Returns point at time 't' (between 0 and 1) along bezier curve defined by 4 points (anchor_1, control_1, control_2, anchor_2)
+        public static Vector3 EvaluateCurve (Vector3[] points, float t) {
+            return EvaluateCurve (points[0], points[1], points[2], points[3], t);
+        }
+
+        /// Returns point at time 't' (between 0 and 1)  along bezier curve defined by 4 points (anchor_1, control_1, control_2, anchor_2)
+        public static Vector3 EvaluateCurve (Vector3 a1, Vector3 c1, Vector3 c2, Vector3 a2, float t) {
+            t = Mathf.Clamp01 (t);
+            return (1 - t) * (1 - t) * (1 - t) * a1 + 3 * (1 - t) * (1 - t) * t * c1 + 3 * (1 - t) * t * t * c2 + t * t * t * a2;
+        }
+
+        /// Returns a vector tangent to the point at time 't'
+        /// This is the vector tangent to the curve at that point
+        public static Vector3 EvaluateCurveDerivative (Vector3[] points, float t) {
+            return EvaluateCurveDerivative (points[0], points[1], points[2], points[3], t);
+        }
+
+        /// Calculates the derivative of the curve at time 't'
+        /// This is the vector tangent to the curve at that point
+        public static Vector3 EvaluateCurveDerivative (Vector3 a1, Vector3 c1, Vector3 c2, Vector3 a2, float t) {
+            t = Mathf.Clamp01 (t);
+            return 3 * (1 - t) * (1 - t) * (c1 - a1) + 6 * (1 - t) * t * (c2 - c1) + 3 * t * t * (a2 - c2);
+        }
+
+        /// Returns the second derivative of the curve at time 't'
+        public static Vector3 EvaluateCurveSecondDerivative (Vector3[] points, float t) {
+            return EvaluateCurveSecondDerivative (points[0], points[1], points[2], points[3], t);
+        }
+
+        ///Returns the second derivative of the curve at time 't'
+        public static Vector3 EvaluateCurveSecondDerivative (Vector3 a1, Vector3 c1, Vector3 c2, Vector3 a2, float t) {
+            t = Mathf.Clamp01 (t);
+            return 6 * (1 - t) * (c2 - 2 * c1 + a1) + 6 * t * (a2 - 2 * c2 + c1);
+        }
+
+        /// Calculates the normal vector (vector perpendicular to the curve) at specified time
+        public static Vector3 Normal (Vector3[] points, float t) {
+            return Normal (points[0], points[1], points[2], points[3], t);
+        }
+
+        /// Calculates the normal vector (vector perpendicular to the curve) at specified time
+        public static Vector3 Normal (Vector3 a1, Vector3 c1, Vector3 c2, Vector3 a2, float t) {
+            Vector3 tangent = EvaluateCurveDerivative (a1, c1, c2, a2, t);
+            Vector3 nextTangent = EvaluateCurveSecondDerivative (a1, c1, c2, a2, t);
+            Vector3 c = Vector3.Cross (nextTangent, tangent);
+            return Vector3.Cross (c, tangent).normalized;
+        }
+
+        public static Bounds CalculateSegmentBounds (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) {
+            MinMax3D minMax = new MinMax3D ();
+            minMax.AddValue (p0);
+            minMax.AddValue (p3);
+
+            List<float> extremePointTimes = ExtremePointTimes (p0,p1,p2,p3);
+            foreach (float t in extremePointTimes) {
+                minMax.AddValue (CubicBezierUtility.EvaluateCurve (p0, p1, p2, p3, t));
+            }
+
+            return new Bounds ((minMax.Min + minMax.Max) / 2, minMax.Max - minMax.Min);
+        }
+
+        /// Splits curve into two curves at time t. Returns 2 arrays of 4 points.
+        public static Vector3[][] SplitCurve (Vector3[] points, float t) {
+            Vector3 a1 = Vector3.Lerp (points[0], points[1], t);
+            Vector3 a2 = Vector3.Lerp (points[1], points[2], t);
+            Vector3 a3 = Vector3.Lerp (points[2], points[3], t);
+            Vector3 b1 = Vector3.Lerp (a1, a2, t);
+            Vector3 b2 = Vector3.Lerp (a2, a3, t);
+            Vector3 pointOnCurve = Vector3.Lerp (b1, b2, t);
+
+            return new Vector3[][] {
+                new Vector3[] { points[0], a1, b1, pointOnCurve },
+                    new Vector3[] { pointOnCurve, b2, a3, points[3] }
+            };
+        }
+
+        // Crude, but fast estimation of curve length.
+        public static float EstimateCurveLength (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) {
+            float controlNetLength = (p0 - p1).magnitude + (p1 - p2).magnitude + (p2 - p3).magnitude;
+            float estimatedCurveLength = (p0 - p3).magnitude + controlNetLength / 2f;
+            return estimatedCurveLength;
+        }
+
+        /// Times of stationary points on curve (points where derivative is zero on any axis)
+        public static List<float> ExtremePointTimes (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) {
+            // coefficients of derivative function
+            Vector3 a = 3 * (-p0 + 3 * p1 - 3 * p2 + p3);
+            Vector3 b = 6 * (p0 - 2 * p1 + p2);
+            Vector3 c = 3 * (p1 - p0);
+
+            List<float> times = new List<float> ();
+            times.AddRange (StationaryPointTimes (a.x, b.x, c.x));
+            times.AddRange (StationaryPointTimes (a.y, b.y, c.y));
+            times.AddRange (StationaryPointTimes (a.z, b.z, c.z));
+            return times;
+        }
+
+        // Finds times of stationary points on curve defined by ax^2 + bx + c.
+        // Only times between 0 and 1 are considered as Bezier only uses values in that range
+        static IEnumerable<float> StationaryPointTimes (float a, float b, float c) {
+            List<float> times = new List<float> ();
+
+            // from quadratic equation: y = [-b +- sqrt(b^2 - 4ac)]/2a
+            if (a != 0) {
+                float discriminant = b * b - 4 * a * c;
+                if (discriminant >= 0) {
+                    float s = Mathf.Sqrt (discriminant);
+                    float t1 = (-b + s) / (2 * a);
+                    if (t1 >= 0 && t1 <= 1) {
+                        times.Add (t1);
+                    }
+
+                    if (discriminant != 0) {
+                        float t2 = (-b - s) / (2 * a);
+
+                        if (t2 >= 0 && t2 <= 1) {
+                            times.Add (t2);
+                        }
+                    }
+                }
+            }
+            return times;
+        }
+
+    }
+}

+ 13 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/CubicBezierUtility.cs.meta

@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: c66a6536bb2d641558729d6da1ec7594
+timeCreated: 1519565538
+licenseType: Pro
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 168 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/MathUtility.cs

@@ -0,0 +1,168 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace PathCreation.Utility {
+    public static class MathUtility {
+
+        // Transform point from local to world space
+        public static Vector3 TransformPoint (Vector3 p, Transform t, PathSpace space) {
+            // path only works correctly for uniform scales, so average out xyz global scale
+            float scale = Vector3.Dot (t.lossyScale, Vector3.one) / 3;
+            Vector3 constrainedPos = t.position;
+            Quaternion constrainedRot = t.rotation;
+            ConstrainPosRot (ref constrainedPos, ref constrainedRot, space);
+            return constrainedRot * p * scale + constrainedPos;
+        }
+
+        // Transform point from world to local space
+        public static Vector3 InverseTransformPoint (Vector3 p, Transform t, PathSpace space) {
+            Vector3 constrainedPos = t.position;
+            Quaternion constrainedRot = t.rotation;
+            ConstrainPosRot (ref constrainedPos, ref constrainedRot, space);
+
+            // path only works correctly for uniform scales, so average out xyz global scale
+            float scale = Vector3.Dot (t.lossyScale, Vector3.one) / 3;
+            var offset = p - constrainedPos;
+
+            return Quaternion.Inverse (constrainedRot) * offset / scale;
+        }
+
+        // Transform vector from local to world space (affected by rotation and scale, but not position)
+        public static Vector3 TransformVector (Vector3 p, Transform t, PathSpace space) {
+            // path only works correctly for uniform scales, so average out xyz global scale
+            float scale = Vector3.Dot (t.lossyScale, Vector3.one) / 3;
+            Quaternion constrainedRot = t.rotation;
+            ConstrainRot (ref constrainedRot, space);
+            return constrainedRot * p * scale;
+        }
+
+        // Transform vector from world to local space (affected by rotation and scale, but not position)
+        public static Vector3 InverseTransformVector (Vector3 p, Transform t, PathSpace space) {
+            Quaternion constrainedRot = t.rotation;
+            ConstrainRot (ref constrainedRot, space);
+            // path only works correctly for uniform scales, so average out xyz global scale
+            float scale = Vector3.Dot (t.lossyScale, Vector3.one) / 3;
+            return Quaternion.Inverse (constrainedRot) * p / scale;
+        }
+
+        // Transform vector from local to world space (affected by rotation, but not position or scale)
+        public static Vector3 TransformDirection (Vector3 p, Transform t, PathSpace space) {
+            Quaternion constrainedRot = t.rotation;
+            ConstrainRot (ref constrainedRot, space);
+            return constrainedRot * p;
+        }
+
+        // Transform vector from world to local space (affected by rotation, but not position or scale)
+        public static Vector3 InverseTransformDirection (Vector3 p, Transform t, PathSpace space) {
+            Quaternion constrainedRot = t.rotation;
+            ConstrainRot (ref constrainedRot, space);
+            return Quaternion.Inverse (constrainedRot) * p;
+        }
+
+        public static bool LineSegmentsIntersect (Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2) {
+            float d = (b2.x - b1.x) * (a1.y - a2.y) - (a1.x - a2.x) * (b2.y - b1.y);
+            if (d == 0)
+                return false;
+            float t = ((b1.y - b2.y) * (a1.x - b1.x) + (b2.x - b1.x) * (a1.y - b1.y)) / d;
+            float u = ((a1.y - a2.y) * (a1.x - b1.x) + (a2.x - a1.x) * (a1.y - b1.y)) / d;
+
+            return t >= 0 && t <= 1 && u >= 0 && u <= 1;
+        }
+
+        public static bool LinesIntersect (Vector2 a1, Vector2 a2, Vector2 a3, Vector2 a4) {
+            return (a1.x - a2.x) * (a3.y - a4.y) - (a1.y - a2.y) * (a3.x - a4.x) != 0;
+        }
+
+        public static Vector2 PointOfLineLineIntersection (Vector2 a1, Vector2 a2, Vector2 a3, Vector2 a4) {
+            float d = (a1.x - a2.x) * (a3.y - a4.y) - (a1.y - a2.y) * (a3.x - a4.x);
+            if (d == 0) {
+                Debug.LogError ("Lines are parallel, please check that this is not the case before calling line intersection method");
+                return Vector2.zero;
+            } else {
+                float n = (a1.x - a3.x) * (a3.y - a4.y) - (a1.y - a3.y) * (a3.x - a4.x);
+                float t = n / d;
+                return a1 + (a2 - a1) * t;
+            }
+        }
+
+        public static Vector2 ClosestPointOnLineSegment (Vector2 p, Vector2 a, Vector2 b) {
+            Vector2 aB = b - a;
+            Vector2 aP = p - a;
+            float sqrLenAB = aB.sqrMagnitude;
+
+            if (sqrLenAB == 0)
+                return a;
+
+            float t = Mathf.Clamp01 (Vector2.Dot (aP, aB) / sqrLenAB);
+            return a + aB * t;
+        }
+
+        public static Vector3 ClosestPointOnLineSegment (Vector3 p, Vector3 a, Vector3 b) {
+            Vector3 aB = b - a;
+            Vector3 aP = p - a;
+            float sqrLenAB = aB.sqrMagnitude;
+
+            if (sqrLenAB == 0)
+                return a;
+
+            float t = Mathf.Clamp01 (Vector3.Dot (aP, aB) / sqrLenAB);
+            return a + aB * t;
+        }
+
+        public static int SideOfLine (Vector2 a, Vector2 b, Vector2 c) {
+            return (int) Mathf.Sign ((c.x - a.x) * (-b.y + a.y) + (c.y - a.y) * (b.x - a.x));
+        }
+
+        /// returns the smallest angle between ABC. Never greater than 180
+        public static float MinAngle (Vector3 a, Vector3 b, Vector3 c) {
+            return Vector3.Angle ((a - b), (c - b));
+        }
+
+        public static bool PointInTriangle (Vector2 a, Vector2 b, Vector2 c, Vector2 p) {
+            float area = 0.5f * (-b.y * c.x + a.y * (-b.x + c.x) + a.x * (b.y - c.y) + b.x * c.y);
+            float s = 1 / (2 * area) * (a.y * c.x - a.x * c.y + (c.y - a.y) * p.x + (a.x - c.x) * p.y);
+            float t = 1 / (2 * area) * (a.x * b.y - a.y * b.x + (a.y - b.y) * p.x + (b.x - a.x) * p.y);
+            return s >= 0 && t >= 0 && (s + t) <= 1;
+        }
+
+        public static bool PointsAreClockwise (Vector2[] points) {
+            float signedArea = 0;
+            for (int i = 0; i < points.Length; i++) {
+                int nextIndex = (i + 1) % points.Length;
+                signedArea += (points[nextIndex].x - points[i].x) * (points[nextIndex].y + points[i].y);
+            }
+
+            return signedArea >= 0;
+        }
+
+        static void ConstrainPosRot (ref Vector3 pos, ref Quaternion rot, PathSpace space) {
+            if (space == PathSpace.xy) {
+                var eulerAngles = rot.eulerAngles;
+                if (eulerAngles.x != 0 || eulerAngles.y != 0) {
+                    rot = Quaternion.AngleAxis (eulerAngles.z, Vector3.forward);
+                }
+                pos = new Vector3 (pos.x, pos.y, 0);
+            } else if (space == PathSpace.xz) {
+                var eulerAngles = rot.eulerAngles;
+                if (eulerAngles.x != 0 || eulerAngles.z != 0) {
+                    rot = Quaternion.AngleAxis (eulerAngles.y, Vector3.up);
+                }
+                pos = new Vector3 (pos.x, 0, pos.z);
+            }
+        }
+
+        static void ConstrainRot (ref Quaternion rot, PathSpace space) {
+            if (space == PathSpace.xy) {
+                var eulerAngles = rot.eulerAngles;
+                if (eulerAngles.x != 0 || eulerAngles.y != 0) {
+                    rot = Quaternion.AngleAxis (eulerAngles.z, Vector3.forward);
+                }
+            } else if (space == PathSpace.xz) {
+                var eulerAngles = rot.eulerAngles;
+                if (eulerAngles.x != 0 || eulerAngles.z != 0) {
+                    rot = Quaternion.AngleAxis (eulerAngles.y, Vector3.up);
+                }
+            }
+        }
+    }
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/MathUtility.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 096bae1d1ed960d4bb7605dce06767c1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 139 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/VertexPathUtility.cs

@@ -0,0 +1,139 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace PathCreation.Utility
+{
+    public static class VertexPathUtility
+    {
+
+		public static PathSplitData SplitBezierPathByAngleError(BezierPath bezierPath, float maxAngleError, float minVertexDst, float accuracy)
+        {
+			PathSplitData splitData = new PathSplitData();
+
+            splitData.vertices.Add(bezierPath[0]);
+            splitData.tangents.Add(CubicBezierUtility.EvaluateCurveDerivative(bezierPath.GetPointsInSegment(0), 0).normalized);
+            splitData.cumulativeLength.Add(0);
+            splitData.anchorVertexMap.Add(0);
+			splitData.minMax.AddValue(bezierPath[0]);
+
+            Vector3 prevPointOnPath = bezierPath[0];
+            Vector3 lastAddedPoint = bezierPath[0];
+
+            float currentPathLength = 0;
+            float dstSinceLastVertex = 0;
+
+            // Go through all segments and split up into vertices
+            for (int segmentIndex = 0; segmentIndex < bezierPath.NumSegments; segmentIndex++)
+            {
+                Vector3[] segmentPoints = bezierPath.GetPointsInSegment(segmentIndex);
+                float estimatedSegmentLength = CubicBezierUtility.EstimateCurveLength(segmentPoints[0], segmentPoints[1], segmentPoints[2], segmentPoints[3]);
+                int divisions = Mathf.CeilToInt(estimatedSegmentLength * accuracy);
+                float increment = 1f / divisions;
+
+                for (float t = increment; t <= 1; t += increment)
+                {
+                    bool isLastPointOnPath = (t + increment > 1 && segmentIndex == bezierPath.NumSegments - 1);
+                    if (isLastPointOnPath)
+                    {
+                        t = 1;
+                    }
+                    Vector3 pointOnPath = CubicBezierUtility.EvaluateCurve(segmentPoints, t);
+                    Vector3 nextPointOnPath = CubicBezierUtility.EvaluateCurve(segmentPoints, t + increment);
+
+                    // angle at current point on path
+                    float localAngle = 180 - MathUtility.MinAngle(prevPointOnPath, pointOnPath, nextPointOnPath);
+                    // angle between the last added vertex, the current point on the path, and the next point on the path
+                    float angleFromPrevVertex = 180 - MathUtility.MinAngle(lastAddedPoint, pointOnPath, nextPointOnPath);
+                    float angleError = Mathf.Max(localAngle, angleFromPrevVertex);
+
+
+                    if ((angleError > maxAngleError && dstSinceLastVertex >= minVertexDst) || isLastPointOnPath)
+                    {
+
+                        currentPathLength += (lastAddedPoint - pointOnPath).magnitude;
+                        splitData.cumulativeLength.Add(currentPathLength);
+                        splitData.vertices.Add(pointOnPath);
+                        splitData.tangents.Add(CubicBezierUtility.EvaluateCurveDerivative(segmentPoints, t).normalized);
+						splitData.minMax.AddValue(pointOnPath);
+                        dstSinceLastVertex = 0;
+                        lastAddedPoint = pointOnPath;
+                    }
+                    else
+                    {
+                        dstSinceLastVertex += (pointOnPath - prevPointOnPath).magnitude;
+                    }
+                    prevPointOnPath = pointOnPath;
+                }
+                splitData.anchorVertexMap.Add(splitData.vertices.Count - 1);
+            }
+			return splitData;
+		}
+
+		public static PathSplitData SplitBezierPathEvenly(BezierPath bezierPath, float spacing, float accuracy)
+        {
+			PathSplitData splitData = new PathSplitData();
+
+            splitData.vertices.Add(bezierPath[0]);
+            splitData.tangents.Add(CubicBezierUtility.EvaluateCurveDerivative(bezierPath.GetPointsInSegment(0), 0).normalized);
+            splitData.cumulativeLength.Add(0);
+            splitData.anchorVertexMap.Add(0);
+			splitData.minMax.AddValue(bezierPath[0]);
+
+            Vector3 prevPointOnPath = bezierPath[0];
+            Vector3 lastAddedPoint = bezierPath[0];
+
+            float currentPathLength = 0;
+            float dstSinceLastVertex = 0;
+
+            // Go through all segments and split up into vertices
+            for (int segmentIndex = 0; segmentIndex < bezierPath.NumSegments; segmentIndex++)
+            {
+                Vector3[] segmentPoints = bezierPath.GetPointsInSegment(segmentIndex);
+                float estimatedSegmentLength = CubicBezierUtility.EstimateCurveLength(segmentPoints[0], segmentPoints[1], segmentPoints[2], segmentPoints[3]);
+                int divisions = Mathf.CeilToInt(estimatedSegmentLength * accuracy);
+                float increment = 1f / divisions;
+
+                for (float t = increment; t <= 1; t += increment)
+                {
+                    bool isLastPointOnPath = (t + increment > 1 && segmentIndex == bezierPath.NumSegments - 1);
+                    if (isLastPointOnPath)
+                    {
+                        t = 1;
+                    }
+                    Vector3 pointOnPath = CubicBezierUtility.EvaluateCurve(segmentPoints, t);
+					dstSinceLastVertex += (pointOnPath - prevPointOnPath).magnitude;
+
+					// If vertices are now too far apart, go back by amount we overshot by
+					if (dstSinceLastVertex > spacing) {
+						float overshootDst = dstSinceLastVertex - spacing;
+						pointOnPath += (prevPointOnPath-pointOnPath).normalized * overshootDst;
+						t-=increment;
+					}
+
+                    if (dstSinceLastVertex >= spacing || isLastPointOnPath)
+                    {
+                        currentPathLength += (lastAddedPoint - pointOnPath).magnitude;
+                        splitData.cumulativeLength.Add(currentPathLength);
+                        splitData.vertices.Add(pointOnPath);
+                        splitData.tangents.Add(CubicBezierUtility.EvaluateCurveDerivative(segmentPoints, t).normalized);
+						splitData.minMax.AddValue(pointOnPath);
+                        dstSinceLastVertex = 0;
+                        lastAddedPoint = pointOnPath;
+                    }
+                    prevPointOnPath = pointOnPath;
+                }
+                splitData.anchorVertexMap.Add(splitData.vertices.Count - 1);
+            }
+			return splitData;
+		}
+
+       
+	   public class PathSplitData {
+		   public List<Vector3> vertices = new List<Vector3>();
+		   public List<Vector3> tangents = new List<Vector3>();
+		   public List<float> cumulativeLength = new List<float>();
+		   public List<int> anchorVertexMap = new List<int>();
+		   public MinMax3D minMax = new MinMax3D();
+	   }
+    }
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Core/Runtime/Utility/VertexPathUtility.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5505526f3c472e8499fa7ce169410ace
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Core/Settings.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4f9b1508dc64040469b4b1ee117d27a9
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 36 - 0
ActionTowerDefense/Assets/PathCreator/Core/Settings/GlobalDisplaySettings.asset

@@ -0,0 +1,36 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 0}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 46d5e8d803e252f4499b52e657f8e1a2, type: 3}
+  m_Name: GlobalDisplaySettings
+  m_EditorClassIdentifier: 
+  anchorSize: 10
+  controlSize: 7
+  visibleBehindObjects: 1
+  visibleWhenNotSelected: 1
+  hideAutoControls: 1
+  anchorShape: 0
+  controlShape: 0
+  anchor: {r: 1, g: 0.3726415, b: 0.3726415, a: 1}
+  anchorHighlighted: {r: 0.735849, g: 0.03818085, b: 0.03818085, a: 1}
+  anchorSelected: {r: 1, g: 1, b: 1, a: 1}
+  control: {r: 0.35, g: 0.6, b: 1, a: 1}
+  controlHighlighted: {r: 0.19579923, g: 0.19579923, b: 0.754717, a: 1}
+  controlSelected: {r: 1, g: 1, b: 1, a: 1}
+  handleDisabled: {r: 1, g: 1, b: 1, a: 0.2}
+  controlLine: {r: 0, g: 0, b: 0, a: 0.7254902}
+  bezierPath: {r: 0, g: 1, b: 0, a: 1}
+  highlightedPath: {r: 1, g: 0.6, b: 0, a: 1}
+  bounds: {r: 1, g: 1, b: 1, a: 0.4}
+  segmentBounds: {r: 1, g: 1, b: 1, a: 0.4}
+  vertexPath: {r: 1, g: 1, b: 1, a: 1}
+  normals: {r: 1, g: 0.92156863, b: 0.015686275, a: 1}
+  normalsLength: 0.198

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Core/Settings/GlobalDisplaySettings.asset.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 35fab21375bf12f4b96eba4dafa4ad30
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 11400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Documentation.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7f53e212088d741abad12e1f2315eee7
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
ActionTowerDefense/Assets/PathCreator/Documentation/Documentation.pdf


+ 7 - 0
ActionTowerDefense/Assets/PathCreator/Documentation/Documentation.pdf.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: e7b865996e4d342a39bbea59a2e43a53
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 9 - 0
ActionTowerDefense/Assets/PathCreator/Examples.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 856133338e5935c4ea7215ea837b00da
+folderAsset: yes
+timeCreated: 1546380202
+licenseType: Pro
+DefaultImporter:
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ba68311e0a74e694fbd8f64185d03175
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 76 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Black.mat

@@ -0,0 +1,76 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 6
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_Name: Black
+  m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
+  m_ShaderKeywords: 
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses: []
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Floats:
+    - _BumpScale: 1
+    - _Cutoff: 0.5
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _GlossMapScale: 1
+    - _Glossiness: 0.2
+    - _GlossyReflections: 1
+    - _Metallic: 0
+    - _Mode: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.02
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _UVSec: 0
+    - _ZWrite: 1
+    m_Colors:
+    - _Color: {r: 0.103773594, g: 0.103773594, b: 0.103773594, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Black.mat.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 69561553b86bde34da494d1ffed3ba45
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 76 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Blue.mat

@@ -0,0 +1,76 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 6
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_Name: Blue
+  m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
+  m_ShaderKeywords: 
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses: []
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Floats:
+    - _BumpScale: 1
+    - _Cutoff: 0.5
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _GlossMapScale: 1
+    - _Glossiness: 0.2
+    - _GlossyReflections: 1
+    - _Metallic: 0
+    - _Mode: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.02
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _UVSec: 0
+    - _ZWrite: 1
+    m_Colors:
+    - _Color: {r: 0.30584726, g: 0.5791927, b: 0.8207547, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Blue.mat.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 5c270a73328a99e439fec44a0cf3a17d
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 77 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Brown.mat

@@ -0,0 +1,77 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 6
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Brown
+  m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
+  m_ShaderKeywords: 
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses: []
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 10.66}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 10.66}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Floats:
+    - _BumpScale: 1
+    - _Cutoff: 0.5
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _GlossMapScale: 1
+    - _Glossiness: 0
+    - _GlossyReflections: 1
+    - _Metallic: 0
+    - _Mode: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.02
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _UVSec: 0
+    - _ZWrite: 1
+    m_Colors:
+    - _Color: {r: 0.4528302, g: 0.19663213, b: 0.10466359, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

+ 10 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Brown.mat.meta

@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: d5b3a558a1e7f4a4182b166bb2f27cf7
+timeCreated: 1519840206
+licenseType: Pro
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 77 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Dark Grey.mat

@@ -0,0 +1,77 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 6
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Dark Grey
+  m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
+  m_ShaderKeywords: 
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses: []
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Floats:
+    - _BumpScale: 1
+    - _Cutoff: 0.5
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _GlossMapScale: 1
+    - _Glossiness: 0
+    - _GlossyReflections: 1
+    - _Metallic: 0
+    - _Mode: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.02
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _UVSec: 0
+    - _ZWrite: 1
+    m_Colors:
+    - _Color: {r: 0.16037738, g: 0.16037738, b: 0.16037738, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Dark Grey.mat.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 407e3de4fbbcf4a99b17bf5aac2d28d8
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 76 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Green.mat

@@ -0,0 +1,76 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 6
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_Name: Green
+  m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
+  m_ShaderKeywords: 
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses: []
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Floats:
+    - _BumpScale: 1
+    - _Cutoff: 0.5
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _GlossMapScale: 1
+    - _Glossiness: 0.2
+    - _GlossyReflections: 1
+    - _Metallic: 0
+    - _Mode: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.02
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _UVSec: 0
+    - _ZWrite: 1
+    m_Colors:
+    - _Color: {r: 0.46839345, g: 0.81960785, b: 0.30588233, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Green.mat.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 9ca80467a033e954a8b9ad8601d6f4c7
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 76 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Red.mat

@@ -0,0 +1,76 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 6
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_Name: Red
+  m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
+  m_ShaderKeywords: 
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses: []
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Floats:
+    - _BumpScale: 1
+    - _Cutoff: 0.5
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _GlossMapScale: 1
+    - _Glossiness: 0.2
+    - _GlossyReflections: 1
+    - _Metallic: 0
+    - _Mode: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.02
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _UVSec: 0
+    - _ZWrite: 1
+    m_Colors:
+    - _Color: {r: 0.9528302, g: 0.23820755, b: 0.26590508, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Red.mat.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 01763a1c279a5cd4d8f897f6b6cdbae5
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road Texture.png


+ 74 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road Texture.png.meta

@@ -0,0 +1,74 @@
+fileFormatVersion: 2
+guid: eef7def8a6d89134284369bbe0145515
+timeCreated: 1546381451
+licenseType: Pro
+TextureImporter:
+  fileIDToRecycleName: {}
+  serializedVersion: 4
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 1
+    sRGBTexture: 1
+    linearTexture: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapsPreserveCoverage: 0
+    alphaTestReferenceValue: 0.5
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: 0.25
+    normalMapFilter: 0
+  isReadable: 0
+  grayScaleToAlpha: 0
+  generateCubemap: 6
+  cubemapConvolution: 0
+  seamlessCubemap: 0
+  textureFormat: 1
+  maxTextureSize: 2048
+  textureSettings:
+    serializedVersion: 2
+    filterMode: -1
+    aniso: -1
+    mipBias: -1
+    wrapU: -1
+    wrapV: -1
+    wrapW: -1
+  nPOTScale: 1
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: 0.5, y: 0.5}
+  spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+  spritePixelsToUnits: 100
+  alphaUsage: 1
+  alphaIsTransparency: 0
+  spriteTessellationDetail: -1
+  textureType: 0
+  textureShape: 1
+  maxTextureSizeSet: 0
+  compressionQualitySet: 0
+  textureFormatSet: 0
+  platformSettings:
+  - buildTarget: DefaultTexturePlatform
+    maxTextureSize: 2048
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+  spriteSheet:
+    serializedVersion: 2
+    sprites: []
+    outline: []
+    physicsShape: []
+  spritePackingTag: 
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 76 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road Underside.mat

@@ -0,0 +1,76 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 6
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_Name: Road Underside
+  m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
+  m_ShaderKeywords: 
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses: []
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 10.66}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 10.66}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Floats:
+    - _BumpScale: 1
+    - _Cutoff: 0.5
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _GlossMapScale: 1
+    - _Glossiness: 0
+    - _GlossyReflections: 1
+    - _Metallic: 0
+    - _Mode: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.02
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _UVSec: 0
+    - _ZWrite: 1
+    m_Colors:
+    - _Color: {r: 0.047169805, g: 0.047169805, b: 0.047169805, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

+ 10 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road Underside.mat.meta

@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: c1d8d882244c5344fa86a8fd23246f81
+timeCreated: 1519840206
+licenseType: Pro
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 76 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road.mat

@@ -0,0 +1,76 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+  serializedVersion: 6
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_Name: Road
+  m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
+  m_ShaderKeywords: 
+  m_LightmapFlags: 4
+  m_EnableInstancingVariants: 0
+  m_DoubleSidedGI: 0
+  m_CustomRenderQueue: -1
+  stringTagMap: {}
+  disabledShaderPasses: []
+  m_SavedProperties:
+    serializedVersion: 3
+    m_TexEnvs:
+    - _BumpMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailAlbedoMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailMask:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _DetailNormalMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _EmissionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _MainTex:
+        m_Texture: {fileID: 2800000, guid: eef7def8a6d89134284369bbe0145515, type: 3}
+        m_Scale: {x: 1, y: 8}
+        m_Offset: {x: 0, y: 0}
+    - _MetallicGlossMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _OcclusionMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    - _ParallaxMap:
+        m_Texture: {fileID: 0}
+        m_Scale: {x: 1, y: 1}
+        m_Offset: {x: 0, y: 0}
+    m_Floats:
+    - _BumpScale: 1
+    - _Cutoff: 0.5
+    - _DetailNormalMapScale: 1
+    - _DstBlend: 0
+    - _GlossMapScale: 1
+    - _Glossiness: 0.153
+    - _GlossyReflections: 1
+    - _Metallic: 0
+    - _Mode: 0
+    - _OcclusionStrength: 1
+    - _Parallax: 0.02
+    - _SmoothnessTextureChannel: 0
+    - _SpecularHighlights: 1
+    - _SrcBlend: 1
+    - _UVSec: 0
+    - _ZWrite: 1
+    m_Colors:
+    - _Color: {r: 1, g: 1, b: 1, a: 1}
+    - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}

+ 9 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Materials/Road.mat.meta

@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: b5df4735192845740bd11076dc9cdc99
+timeCreated: 1546381442
+licenseType: Pro
+NativeFormatImporter:
+  mainObjectFileID: 2100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Prefabs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3331696fd1c6e4ce399332471e58fe60
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 79 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Cube.prefab

@@ -0,0 +1,79 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &4033822839321833552
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 979840955744105011}
+  - component: {fileID: 590364381998773281}
+  - component: {fileID: 5190809732636690155}
+  m_Layer: 0
+  m_Name: Cube
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &979840955744105011
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4033822839321833552}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: -1.1922646, y: -0.4048736, z: -0.2549243}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!33 &590364381998773281
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4033822839321833552}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &5190809732636690155
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 4033822839321833552}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0

+ 7 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Cube.prefab.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: f19b52bc2573b4e508c60232d5ba4c53
+PrefabImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 450 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Follower.prefab

@@ -0,0 +1,450 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1001 &100100000
+Prefab:
+  m_ObjectHideFlags: 1
+  serializedVersion: 2
+  m_Modification:
+    m_TransformParent: {fileID: 0}
+    m_Modifications: []
+    m_RemovedComponents: []
+  m_ParentPrefab: {fileID: 0}
+  m_RootGameObject: {fileID: 1576909240372392}
+  m_IsPrefabParent: 1
+--- !u!1 &1048366265463928
+GameObject:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 4175983145834568}
+  - component: {fileID: 33949624754287046}
+  - component: {fileID: 23998214817209668}
+  m_Layer: 0
+  m_Name: Body
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!1 &1142303417255900
+GameObject:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 4919219541973858}
+  - component: {fileID: 33545565440070206}
+  - component: {fileID: 23648042348708658}
+  m_Layer: 0
+  m_Name: Left
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!1 &1179929860508712
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 4969400159738430}
+  m_Layer: 0
+  m_Name: Model
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!1 &1402382065157418
+GameObject:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 4420413991641732}
+  - component: {fileID: 33735273466746142}
+  - component: {fileID: 23463250516226866}
+  m_Layer: 0
+  m_Name: Forward
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!1 &1466481028253768
+GameObject:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 4175567933537352}
+  - component: {fileID: 33944734216049334}
+  - component: {fileID: 23616845451545226}
+  m_Layer: 0
+  m_Name: Right
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!1 &1576909240372392
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 4125965570099986}
+  - component: {fileID: 114548013775708692}
+  m_Layer: 0
+  m_Name: Follower
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!1 &1591658747683034
+GameObject:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 4243308877940266}
+  - component: {fileID: 33880363704101016}
+  - component: {fileID: 23486494810615104}
+  m_Layer: 0
+  m_Name: Up
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4125965570099986
+Transform:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1576909240372392}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 4969400159738430}
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4175567933537352
+Transform:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1466481028253768}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0.75, y: 0, z: 0}
+  m_LocalScale: {x: 0.5, y: 0.5, z: 0.5}
+  m_Children: []
+  m_Father: {fileID: 4969400159738430}
+  m_RootOrder: 4
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4175983145834568
+Transform:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1048366265463928}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 4969400159738430}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4243308877940266
+Transform:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1591658747683034}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0.75, z: 0}
+  m_LocalScale: {x: 0.5, y: 0.5, z: 0.5}
+  m_Children: []
+  m_Father: {fileID: 4969400159738430}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4420413991641732
+Transform:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1402382065157418}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0.75}
+  m_LocalScale: {x: 0.5, y: 0.5, z: 0.5}
+  m_Children: []
+  m_Father: {fileID: 4969400159738430}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4919219541973858
+Transform:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1142303417255900}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: -0.75, y: 0, z: 0}
+  m_LocalScale: {x: 0.5, y: 0.5, z: 0.5}
+  m_Children: []
+  m_Father: {fileID: 4969400159738430}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!4 &4969400159738430
+Transform:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1179929860508712}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 0.5, y: 0.5, z: 0.5}
+  m_Children:
+  - {fileID: 4175983145834568}
+  - {fileID: 4420413991641732}
+  - {fileID: 4243308877940266}
+  - {fileID: 4919219541973858}
+  - {fileID: 4175567933537352}
+  m_Father: {fileID: 4125965570099986}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &23463250516226866
+MeshRenderer:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1402382065157418}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 4294967295
+  m_Materials:
+  - {fileID: 2100000, guid: 5c270a73328a99e439fec44a0cf3a17d, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!23 &23486494810615104
+MeshRenderer:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1591658747683034}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 4294967295
+  m_Materials:
+  - {fileID: 2100000, guid: 9ca80467a033e954a8b9ad8601d6f4c7, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!23 &23616845451545226
+MeshRenderer:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1466481028253768}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 4294967295
+  m_Materials:
+  - {fileID: 2100000, guid: 01763a1c279a5cd4d8f897f6b6cdbae5, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!23 &23648042348708658
+MeshRenderer:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1142303417255900}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 4294967295
+  m_Materials:
+  - {fileID: 2100000, guid: 01763a1c279a5cd4d8f897f6b6cdbae5, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!23 &23998214817209668
+MeshRenderer:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1048366265463928}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 4294967295
+  m_Materials:
+  - {fileID: 2100000, guid: 69561553b86bde34da494d1ffed3ba45, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &33545565440070206
+MeshFilter:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1142303417255900}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33735273466746142
+MeshFilter:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1402382065157418}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33880363704101016
+MeshFilter:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1591658747683034}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33944734216049334
+MeshFilter:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1466481028253768}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!33 &33949624754287046
+MeshFilter:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1048366265463928}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!114 &114548013775708692
+MonoBehaviour:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1576909240372392}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 33aabe1a2dec93349b06e6e5dc51bc06, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  pathCreator: {fileID: 0}
+  endOfPathInstruction: 0
+  speed: 5

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Follower.prefab.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 761d600d1e80341ac97f3228771ce637
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 100100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 106 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Path.prefab

@@ -0,0 +1,106 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1001 &100100000
+Prefab:
+  m_ObjectHideFlags: 1
+  serializedVersion: 2
+  m_Modification:
+    m_TransformParent: {fileID: 0}
+    m_Modifications: []
+    m_RemovedComponents: []
+  m_ParentPrefab: {fileID: 0}
+  m_RootGameObject: {fileID: 1801384024788032}
+  m_IsPrefabParent: 1
+--- !u!1 &1801384024788032
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 4050403524429934}
+  - component: {fileID: 114462757500385858}
+  m_Layer: 0
+  m_Name: Path
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &4050403524429934
+Transform:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1801384024788032}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &114462757500385858
+MonoBehaviour:
+  m_ObjectHideFlags: 1
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 100100000}
+  m_GameObject: {fileID: 1801384024788032}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 8e5ac92bc18f545cc84cd886ece82b4d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  editorData:
+    _bezierPath:
+      points:
+      - {x: -4.350084, y: -0.6192361, z: 0.36958665}
+      - {x: -4.3119984, y: -0.27224493, z: 2.7627096}
+      - {x: -2.500093, y: 1.7315861, z: 2.2386506}
+      - {x: 0.14839771, y: 1.7105651, z: 2.2219813}
+      - {x: 2.7968912, y: 1.6895441, z: 2.205312}
+      - {x: 4.16408, y: -0.44785511, z: 2.1293974}
+      - {x: 4.3446193, y: -0.6192361, z: 0.36958665}
+      - {x: 4.5251584, y: -0.7906171, z: -1.390224}
+      - {x: 3.2920637, y: 0.7694727, z: -2.9261537}
+      - {x: 0.77272415, y: 0.83640313, z: -3.0503848}
+      - {x: -1.7466154, y: 0.90333354, z: -3.1746159}
+      - {x: -4.3881693, y: -0.9662273, z: -2.0235362}
+      isClosed: 1
+      space: 0
+      controlMode: 1
+      autoControlLength: 0.3
+      boundsUpToDate: 0
+      bounds:
+        m_Center: {x: 0.005727291, y: 0.5250117, z: -0.39030027}
+        m_Extent: {x: 4.3562183, y: 1.1872373, z: 2.6691647}
+      rotation: {x: 0, y: 0, z: 0, w: 1}
+      scale: {x: 2.1736755, y: 2.1736755, z: 2.1736755}
+      perAnchorNormalsAngle:
+      - 0
+      - 0
+      - 0
+      - 0
+      globalNormalsAngle: 69
+      flipNormals: 0
+    vertexPathUpToDate: 1
+    vertexPathMaxAngleError: 0.3
+    vertexPathMinVertexSpacing: 0
+    showTransformTool: 1
+    showPathBounds: 0
+    showPerSegmentBounds: 0
+    displayAnchorPoints: 1
+    displayControlPoints: 1
+    bezierHandleScale: 1
+    globalDisplaySettingsFoldout: 0
+    keepConstantHandleSize: 0
+    showNormalsInVertexMode: 0
+    showBezierPathInVertexMode: 0
+    showDisplayOptions: 0
+    showPathOptions: 1
+    showVertexPathDisplayOptions: 0
+    showVertexPathOptions: 1
+    showNormals: 1
+    showNormalsHelpInfo: 0
+    tabIndex: 0
+  initialized: 1

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Path.prefab.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 2791553a612d84e7c9f3c0a95308376f
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 100100000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 79 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Sphere.prefab

@@ -0,0 +1,79 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &1284304205642556215
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 3168392299219943901}
+  - component: {fileID: 7484263716245627173}
+  - component: {fileID: 4367022514524041713}
+  m_Layer: 0
+  m_Name: Sphere
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &3168392299219943901
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1284304205642556215}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!33 &7484263716245627173
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1284304205642556215}
+  m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &4367022514524041713
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1284304205642556215}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0

+ 7 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Prefabs/Sphere.prefab.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: cb2e1e8aa0d44489c8d332b91c9a4202
+PrefabImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7fa8a76a6a31dba43b3f224aa4c8ef31
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 393 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Follow Path.unity

@@ -0,0 +1,393 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 9
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_IndirectSpecularColor: {r: 0.4465934, g: 0.49642956, b: 0.57482487, a: 1}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 11
+  m_GIWorkflowMode: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_TemporalCoherenceThreshold: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 1
+  m_LightmapEditorSettings:
+    serializedVersion: 10
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_FinalGather: 0
+    m_FinalGatherFiltering: 1
+    m_FinalGatherRayCount: 256
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 2
+    m_BakeBackend: 1
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 500
+    m_PVRBounces: 2
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVRFilteringMode: 2
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 5
+    m_PVRFilteringGaussRadiusAO: 2
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ShowResolutionOverlay: 1
+  m_LightingDataAsset: {fileID: 0}
+  m_UseShadowmask: 1
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 2
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    accuratePlacement: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &184727957
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 184727959}
+  - component: {fileID: 184727958}
+  m_Layer: 0
+  m_Name: Path
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &184727958
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 184727957}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 8e5ac92bc18f545cc84cd886ece82b4d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  editorData:
+    _bezierPath:
+      points:
+      - {x: -4.350084, y: -0.6192361, z: 0.36958665}
+      - {x: -4.3119984, y: -0.27224493, z: 2.7627096}
+      - {x: -2.500093, y: 1.7315861, z: 2.2386506}
+      - {x: 0.14839771, y: 1.7105651, z: 2.2219813}
+      - {x: 2.7968912, y: 1.6895441, z: 2.205312}
+      - {x: 4.16408, y: -0.44785511, z: 2.1293974}
+      - {x: 4.3446193, y: -0.6192361, z: 0.36958665}
+      - {x: 4.5251584, y: -0.7906171, z: -1.390224}
+      - {x: 3.2920637, y: 0.7694727, z: -2.9261537}
+      - {x: 0.77272415, y: 0.83640313, z: -3.0503848}
+      - {x: -1.7466154, y: 0.90333354, z: -3.1746159}
+      - {x: -4.3881693, y: -0.9662273, z: -2.0235362}
+      isClosed: 1
+      space: 0
+      controlMode: 1
+      autoControlLength: 0.3
+      boundsUpToDate: 0
+      bounds:
+        m_Center: {x: 0.005727291, y: 0.5250117, z: -0.39030027}
+        m_Extent: {x: 4.3562183, y: 1.1872373, z: 2.6691647}
+      rotation: {x: 0, y: 0, z: 0, w: 1}
+      scale: {x: 2.1736755, y: 2.1736755, z: 2.1736755}
+      perAnchorNormalsAngle:
+      - 0
+      - 0
+      - 0
+      - 0
+      globalNormalsAngle: 69
+      flipNormals: 0
+    vertexPathUpToDate: 1
+    vertexPathMaxAngleError: 0.3
+    vertexPathMinVertexSpacing: 0
+    showTransformTool: 1
+    showPathBounds: 0
+    showPerSegmentBounds: 0
+    displayAnchorPoints: 1
+    displayControlPoints: 1
+    bezierHandleScale: 1
+    globalDisplaySettingsFoldout: 0
+    keepConstantHandleSize: 0
+    showNormalsInVertexMode: 0
+    showBezierPathInVertexMode: 0
+    showDisplayOptions: 0
+    showPathOptions: 1
+    showVertexPathDisplayOptions: 0
+    showVertexPathOptions: 1
+    showNormals: 0
+    showNormalsHelpInfo: 0
+    tabIndex: 0
+  initialized: 1
+--- !u!4 &184727959
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 184727957}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1001 &1266884696
+Prefab:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_Modification:
+    m_TransformParent: {fileID: 0}
+    m_Modifications:
+    - target: {fileID: 4125965570099986, guid: 761d600d1e80341ac97f3228771ce637, type: 2}
+      propertyPath: m_LocalPosition.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 4125965570099986, guid: 761d600d1e80341ac97f3228771ce637, type: 2}
+      propertyPath: m_LocalPosition.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 4125965570099986, guid: 761d600d1e80341ac97f3228771ce637, type: 2}
+      propertyPath: m_LocalPosition.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 4125965570099986, guid: 761d600d1e80341ac97f3228771ce637, type: 2}
+      propertyPath: m_LocalRotation.x
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 4125965570099986, guid: 761d600d1e80341ac97f3228771ce637, type: 2}
+      propertyPath: m_LocalRotation.y
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 4125965570099986, guid: 761d600d1e80341ac97f3228771ce637, type: 2}
+      propertyPath: m_LocalRotation.z
+      value: 0
+      objectReference: {fileID: 0}
+    - target: {fileID: 4125965570099986, guid: 761d600d1e80341ac97f3228771ce637, type: 2}
+      propertyPath: m_LocalRotation.w
+      value: 1
+      objectReference: {fileID: 0}
+    - target: {fileID: 4125965570099986, guid: 761d600d1e80341ac97f3228771ce637, type: 2}
+      propertyPath: m_RootOrder
+      value: 3
+      objectReference: {fileID: 0}
+    - target: {fileID: 114548013775708692, guid: 761d600d1e80341ac97f3228771ce637,
+        type: 2}
+      propertyPath: pathCreator
+      value: 
+      objectReference: {fileID: 184727958}
+    m_RemovedComponents: []
+  m_ParentPrefab: {fileID: 100100000, guid: 761d600d1e80341ac97f3228771ce637, type: 2}
+  m_IsPrefabParent: 0
+--- !u!1 &1308570505
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1308570508}
+  - component: {fileID: 1308570507}
+  - component: {fileID: 1308570506}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &1308570506
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1308570505}
+  m_Enabled: 1
+--- !u!20 &1308570507
+Camera:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1308570505}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &1308570508
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1308570505}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1844901808
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1844901810}
+  - component: {fileID: 1844901809}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &1844901809
+Light:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1844901808}
+  m_Enabled: 1
+  serializedVersion: 8
+  m_Type: 1
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_Lightmapping: 4
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+--- !u!4 &1844901810
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1844901808}
+  m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}

+ 7 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Follow Path.unity.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: c1e712ad623461e418f182144cf61384
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 973 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Generate Path.unity

@@ -0,0 +1,973 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 9
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_IndirectSpecularColor: {r: 0.44657892, g: 0.4964127, b: 0.5748172, a: 1}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 11
+  m_GIWorkflowMode: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 1
+  m_LightmapEditorSettings:
+    serializedVersion: 12
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 0
+    m_ExtractAmbientOcclusion: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_FinalGather: 0
+    m_FinalGatherFiltering: 1
+    m_FinalGatherRayCount: 256
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 2
+    m_BakeBackend: 1
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 500
+    m_PVRBounces: 2
+    m_PVREnvironmentSampleCount: 500
+    m_PVREnvironmentReferencePointCount: 2048
+    m_PVRFilteringMode: 2
+    m_PVRDenoiserTypeDirect: 0
+    m_PVRDenoiserTypeIndirect: 0
+    m_PVRDenoiserTypeAO: 0
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVREnvironmentMIS: 0
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 5
+    m_PVRFilteringGaussRadiusAO: 2
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ShowResolutionOverlay: 1
+    m_ExportTrainingData: 0
+  m_LightingDataAsset: {fileID: 0}
+  m_UseShadowmask: 1
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 2
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    accuratePlacement: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &244891480
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 244891483}
+  - component: {fileID: 244891482}
+  - component: {fileID: 244891481}
+  m_Layer: 0
+  m_Name: Follower
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!96 &244891481
+TrailRenderer:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 244891480}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 0
+  m_ReflectionProbeUsage: 0
+  m_RenderingLayerMask: 4294967295
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 10306, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+  m_Time: 5
+  m_Parameters:
+    serializedVersion: 3
+    widthMultiplier: 1
+    widthCurve:
+      serializedVersion: 2
+      m_Curve:
+      - serializedVersion: 3
+        time: 0
+        value: 1
+        inSlope: 0
+        outSlope: 0
+        tangentMode: 0
+        weightedMode: 0
+        inWeight: 0.33333334
+        outWeight: 0.33333334
+      - serializedVersion: 3
+        time: 1
+        value: 0
+        inSlope: 0
+        outSlope: 0
+        tangentMode: 0
+        weightedMode: 0
+        inWeight: 0
+        outWeight: 0
+      m_PreInfinity: 2
+      m_PostInfinity: 2
+      m_RotationOrder: 4
+    colorGradient:
+      serializedVersion: 2
+      key0: {r: 0.16470587, g: 0.47597936, b: 1, a: 1}
+      key1: {r: 0.7216981, g: 0.89121073, b: 1, a: 0}
+      key2: {r: 0, g: 0, b: 0, a: 0}
+      key3: {r: 0, g: 0, b: 0, a: 0}
+      key4: {r: 0, g: 0, b: 0, a: 0}
+      key5: {r: 0, g: 0, b: 0, a: 0}
+      key6: {r: 0, g: 0, b: 0, a: 0}
+      key7: {r: 0, g: 0, b: 0, a: 0}
+      ctime0: 0
+      ctime1: 65535
+      ctime2: 0
+      ctime3: 0
+      ctime4: 0
+      ctime5: 0
+      ctime6: 0
+      ctime7: 0
+      atime0: 0
+      atime1: 65535
+      atime2: 0
+      atime3: 0
+      atime4: 0
+      atime5: 0
+      atime6: 0
+      atime7: 0
+      m_Mode: 0
+      m_NumColorKeys: 2
+      m_NumAlphaKeys: 2
+    numCornerVertices: 0
+    numCapVertices: 8
+    alignment: 0
+    textureMode: 0
+    shadowBias: 0
+    generateLightingData: 0
+  m_MinVertexDistance: 0.1
+  m_Autodestruct: 0
+  m_Emitting: 1
+--- !u!114 &244891482
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 244891480}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 33aabe1a2dec93349b06e6e5dc51bc06, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  pathCreator: {fileID: 839433806}
+  endOfPathInstruction: 0
+  speed: 5
+--- !u!4 &244891483
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 244891480}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &315902406
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 315902409}
+  - component: {fileID: 315902408}
+  - component: {fileID: 315902407}
+  m_Layer: 0
+  m_Name: Sphere (4)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!23 &315902407
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 315902406}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 4294967295
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &315902408
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 315902406}
+  m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &315902409
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 315902406}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 6.54, y: -1.75, z: 6.2}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 762964052}
+  m_RootOrder: 4
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &729862344
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 729862347}
+  - component: {fileID: 729862346}
+  - component: {fileID: 729862345}
+  m_Layer: 0
+  m_Name: Sphere (3)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!23 &729862345
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 729862344}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 4294967295
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &729862346
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 729862344}
+  m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &729862347
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 729862344}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 9.1, y: 6.39, z: -3.51}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 762964052}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &762964051
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 762964052}
+  m_Layer: 0
+  m_Name: Waypoints
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &762964052
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 762964051}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 1295418884}
+  - {fileID: 2107402768}
+  - {fileID: 1544419622}
+  - {fileID: 729862347}
+  - {fileID: 315902409}
+  m_Father: {fileID: 0}
+  m_RootOrder: 4
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &839433805
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 839433807}
+  - component: {fileID: 839433808}
+  - component: {fileID: 839433806}
+  m_Layer: 0
+  m_Name: Path
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &839433806
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 839433805}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 8e5ac92bc18f545cc84cd886ece82b4d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  editorData:
+    _bezierPath:
+      points:
+      - {x: -2, y: 0, z: 0}
+      - {x: -1, y: 0.5, z: 0}
+      - {x: 1, y: -0.5, z: 0}
+      - {x: 2, y: 0, z: 0}
+      isClosed: 0
+      space: 0
+      controlMode: 0
+      autoControlLength: 0.3
+      boundsUpToDate: 0
+      bounds:
+        m_Center: {x: 0, y: 0, z: 0}
+        m_Extent: {x: 0, y: 0, z: 0}
+      rotation: {x: 0, y: 0, z: 0, w: 1}
+      scale: {x: 1, y: 1, z: 1}
+      perAnchorNormalsAngle:
+      - 0
+      - 0
+      globalNormalsAngle: 0
+      flipNormals: 0
+    vertexPathUpToDate: 0
+    vertexPathMaxAngleError: 0.3
+    vertexPathMinVertexSpacing: 0.01
+    showTransformTool: 1
+    showPathBounds: 0
+    showPerSegmentBounds: 0
+    displayAnchorPoints: 1
+    displayControlPoints: 1
+    bezierHandleScale: 1
+    globalDisplaySettingsFoldout: 0
+    keepConstantHandleSize: 0
+    showNormalsInVertexMode: 0
+    showBezierPathInVertexMode: 0
+    showDisplayOptions: 0
+    showPathOptions: 1
+    showVertexPathDisplayOptions: 0
+    showVertexPathOptions: 1
+    showNormals: 0
+    showNormalsHelpInfo: 0
+    tabIndex: 0
+  initialized: 1
+--- !u!4 &839433807
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 839433805}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &839433808
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 839433805}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f417e74782fffcd40b77b0fdbe82af04, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  closedLoop: 1
+  waypoints:
+  - {fileID: 1295418884}
+  - {fileID: 2107402768}
+  - {fileID: 1544419622}
+  - {fileID: 729862347}
+  - {fileID: 315902409}
+--- !u!1 &1295418881
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1295418884}
+  - component: {fileID: 1295418883}
+  - component: {fileID: 1295418882}
+  m_Layer: 0
+  m_Name: Sphere
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!23 &1295418882
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1295418881}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 4294967295
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1295418883
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1295418881}
+  m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1295418884
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1295418881}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 762964052}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1407856702
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1407856705}
+  - component: {fileID: 1407856704}
+  - component: {fileID: 1407856703}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &1407856703
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1407856702}
+  m_Enabled: 1
+--- !u!20 &1407856704
+Camera:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1407856702}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+  m_projectionMatrixMode: 1
+  m_GateFitMode: 2
+  m_FOVAxisMode: 0
+  m_SensorSize: {x: 36, y: 24}
+  m_LensShift: {x: 0, y: 0}
+  m_FocalLength: 50
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &1407856705
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1407856702}
+  m_LocalRotation: {x: 0.12969545, y: -0.1184572, z: 0.015607949, w: 0.9843289}
+  m_LocalPosition: {x: 3, y: 8.92, z: -18.23}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 15.012001, y: -13.724001, z: 0}
+--- !u!1 &1544419619
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1544419622}
+  - component: {fileID: 1544419621}
+  - component: {fileID: 1544419620}
+  m_Layer: 0
+  m_Name: Sphere (2)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!23 &1544419620
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1544419619}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 4294967295
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1544419621
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1544419619}
+  m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1544419622
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1544419619}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: -6.17, y: 6.39, z: -10.04}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 762964052}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1612519935
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1612519937}
+  - component: {fileID: 1612519936}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &1612519936
+Light:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1612519935}
+  m_Enabled: 1
+  serializedVersion: 9
+  m_Type: 1
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_InnerSpotAngle: 21.802082
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+    m_CullingMatrixOverride:
+      e00: 1
+      e01: 0
+      e02: 0
+      e03: 0
+      e10: 0
+      e11: 1
+      e12: 0
+      e13: 0
+      e20: 0
+      e21: 0
+      e22: 1
+      e23: 0
+      e30: 0
+      e31: 0
+      e32: 0
+      e33: 1
+    m_UseCullingMatrixOverride: 0
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingLayerMask: 1
+  m_Lightmapping: 4
+  m_LightShadowCasterMode: 0
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+  m_UseBoundingSphereOverride: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+--- !u!4 &1612519937
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1612519935}
+  m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!1 &2107402765
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 2107402768}
+  - component: {fileID: 2107402767}
+  - component: {fileID: 2107402766}
+  m_Layer: 0
+  m_Name: Sphere (1)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!23 &2107402766
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2107402765}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 4294967295
+  m_RendererPriority: 0
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 0
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &2107402767
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2107402765}
+  m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &2107402768
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2107402765}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: -6.17, y: 1.4746776, z: 2.67}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 762964052}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

+ 7 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Generate Path.unity.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 3145d476fb2c7f242875d23b77320de4
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Mesh Examples.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0510b8afe74db46d28644a2bafb7e6f2
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

Datei-Diff unterdrückt, da er zu groß ist
+ 158 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Mesh Examples/Cylinder.unity


+ 7 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Mesh Examples/Cylinder.unity.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 64a23c84aa67047f38f5c81b747e5354
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

Datei-Diff unterdrückt, da er zu groß ist
+ 376 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Mesh Examples/Road.unity


+ 7 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Mesh Examples/Road.unity.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 8f020cfa1fb7ded47926b050b82adbe6
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1944 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Object Placement.unity

@@ -0,0 +1,1944 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 9
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_IndirectSpecularColor: {r: 0.4465934, g: 0.49642956, b: 0.57482487, a: 1}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 11
+  m_GIWorkflowMode: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_TemporalCoherenceThreshold: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 1
+  m_LightmapEditorSettings:
+    serializedVersion: 10
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_FinalGather: 0
+    m_FinalGatherFiltering: 1
+    m_FinalGatherRayCount: 256
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 2
+    m_BakeBackend: 1
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 512
+    m_PVRBounces: 2
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVRFilteringMode: 1
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 5
+    m_PVRFilteringGaussRadiusAO: 2
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ShowResolutionOverlay: 1
+  m_LightingDataAsset: {fileID: 0}
+  m_UseShadowmask: 1
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 2
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    accuratePlacement: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &70188142
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 70188143}
+  - component: {fileID: 70188145}
+  - component: {fileID: 70188144}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &70188143
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 70188142}
+  m_LocalRotation: {x: -0.39927244, y: 0.39927244, z: -0.5835936, w: 0.5835936}
+  m_LocalPosition: {x: 9.822016, y: 0.4048736, z: -10.503309}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 18
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &70188144
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 70188142}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &70188145
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 70188142}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &473136262
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 473136263}
+  - component: {fileID: 473136265}
+  - component: {fileID: 473136264}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &473136263
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 473136262}
+  m_LocalRotation: {x: 0.6124736, y: -0.6124736, z: 0.3533781, w: -0.3533781}
+  m_LocalPosition: {x: -7.4458857, y: 0.4048736, z: -8.243549}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 15
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &473136264
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 473136262}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &473136265
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 473136262}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &664526678
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 664526679}
+  - component: {fileID: 664526681}
+  - component: {fileID: 664526680}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &664526679
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 664526678}
+  m_LocalRotation: {x: 0.25204316, y: -0.25204316, z: -0.66066194, w: 0.660662}
+  m_LocalPosition: {x: 14.085798, y: 0.4048736, z: 17.422533}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 5
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &664526680
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 664526678}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &664526681
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 664526678}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &702570136
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 702570137}
+  - component: {fileID: 702570139}
+  - component: {fileID: 702570138}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &702570137
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 702570136}
+  m_LocalRotation: {x: 0.334829, y: -0.334829, z: -0.6228078, w: 0.6228078}
+  m_LocalPosition: {x: 9.585267, y: 0.4048736, z: 21.53287}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 6
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &702570138
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 702570136}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &702570139
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 702570136}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &877217990
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 877217991}
+  - component: {fileID: 877217993}
+  - component: {fileID: 877217992}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &877217991
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 877217990}
+  m_LocalRotation: {x: -0.497745, y: 0.497745, z: -0.50224495, w: 0.5022449}
+  m_LocalPosition: {x: 9.432941, y: 0.4048736, z: 0.568121}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &877217992
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 877217990}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &877217993
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 877217990}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &947851089
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 947851090}
+  - component: {fileID: 947851092}
+  - component: {fileID: 947851091}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &947851090
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 947851089}
+  m_LocalRotation: {x: -0.2508529, y: 0.2508529, z: -0.6611149, w: 0.6611148}
+  m_LocalPosition: {x: 14.984689, y: 0.4048736, z: -7.3686123}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 19
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &947851091
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 947851089}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &947851092
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 947851089}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &987899030
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 987899031}
+  - component: {fileID: 987899033}
+  - component: {fileID: 987899032}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &987899031
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 987899030}
+  m_LocalRotation: {x: 0.70505685, y: -0.70505685, z: -0.05380449, w: 0.05380449}
+  m_LocalPosition: {x: -14.578905, y: 0.4048736, z: 13.0229435}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 11
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &987899032
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 987899030}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &987899033
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 987899030}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1017046790
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1017046791}
+  - component: {fileID: 1017046793}
+  - component: {fileID: 1017046792}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1017046791
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1017046790}
+  m_LocalRotation: {x: 0.6906611, y: -0.690661, z: -0.15161571, w: 0.15161571}
+  m_LocalPosition: {x: -12.987309, y: 0.4048736, z: 18.90274}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 10
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1017046792
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1017046790}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1017046793
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1017046790}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1035122922
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1035122923}
+  - component: {fileID: 1035122925}
+  - component: {fileID: 1035122924}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1035122923
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1035122922}
+  m_LocalRotation: {x: 0.7070882, y: -0.7070881, z: -0.005134826, w: 0.005134826}
+  m_LocalPosition: {x: -15.071617, y: 0.4048736, z: 6.9375906}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 12
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1035122924
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1035122922}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1035122925
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1035122922}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1045485630
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1045485633}
+  - component: {fileID: 1045485632}
+  - component: {fileID: 1045485631}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &1045485631
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1045485630}
+  m_Enabled: 1
+--- !u!20 &1045485632
+Camera:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1045485630}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &1045485633
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1045485630}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 1, z: -10}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1100876285
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1100876286}
+  m_Layer: 0
+  m_Name: Object Holder
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1100876286
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1100876285}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: -1.1922646, y: -0.4048736, z: -0.2549243}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 1489228399}
+  - {fileID: 877217991}
+  - {fileID: 1305567046}
+  - {fileID: 1726925215}
+  - {fileID: 1836065500}
+  - {fileID: 664526679}
+  - {fileID: 702570137}
+  - {fileID: 1653420825}
+  - {fileID: 1239443495}
+  - {fileID: 1631447300}
+  - {fileID: 1017046791}
+  - {fileID: 987899031}
+  - {fileID: 1035122923}
+  - {fileID: 1451327458}
+  - {fileID: 1863139043}
+  - {fileID: 473136263}
+  - {fileID: 1551300063}
+  - {fileID: 1413329164}
+  - {fileID: 70188143}
+  - {fileID: 947851090}
+  - {fileID: 1743644112}
+  m_Father: {fileID: 0}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1163749077
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1163749079}
+  - component: {fileID: 1163749078}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &1163749078
+Light:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1163749077}
+  m_Enabled: 1
+  serializedVersion: 8
+  m_Type: 1
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_Lightmapping: 4
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+--- !u!4 &1163749079
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1163749077}
+  m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!1 &1173081723
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1173081726}
+  - component: {fileID: 1173081725}
+  - component: {fileID: 1173081724}
+  m_Layer: 0
+  m_Name: Path
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1173081724
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1173081723}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 8e5ac92bc18f545cc84cd886ece82b4d, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  editorData:
+    _bezierPath:
+      points:
+      - {x: 2.177661, y: 0, z: 1.0135708}
+      - {x: 5.2159348, y: 0, z: 0.51950216}
+      - {x: 8.254209, y: 0, z: 0.02543357}
+      - {x: 9.880889, y: 0, z: 0.51335144}
+      - {x: 12.122741, y: 0, z: 1.185788}
+      - {x: 18.025703, y: 0, z: 4.6161985}
+      - {x: 18.365267, y: 0, z: 6.931963}
+      - {x: 18.953577, y: 0, z: 10.944124}
+      - {x: 11.143806, y: 0, z: 20.072712}
+      - {x: 7.4771137, y: 0, z: 21.80445}
+      - {x: 3.4255772, y: 0, z: 23.717943}
+      - {x: -9.652585, y: 0, z: 23.788317}
+      - {x: -12.857204, y: 0, z: 20.656733}
+      - {x: -16.654, y: 0, z: 16.946468}
+      - {x: -17.266878, y: 0, z: 1.2884617}
+      - {x: -14.771961, y: 0, z: -3.397377}
+      - {x: -12.861416, y: 0, z: -6.9856763}
+      - {x: -2.7150939, y: 0, z: -12.051621}
+      - {x: 1.3291776, y: 0, z: -12.463868}
+      - {x: 3.8740497, y: 0, z: -12.723276}
+      - {x: 10.303253, y: 0, z: -10.38054}
+      - {x: 12.403621, y: 0, z: -8.9203615}
+      - {x: 13.973428, y: 0, z: -7.82903}
+      - {x: 15.871395, y: 0, z: -4.956673}
+      - {x: 17.769363, y: 0, z: -2.0843163}
+      isClosed: 0
+      localPosition: {x: 0, y: 0, z: 0}
+      space: 2
+      controlMode: 3
+      autoControlLength: 0.22
+      boundsUpToDate: 1
+      pivot: {x: 1.0637436, y: 0, z: 5.3302784}
+      bounds:
+        m_Center: {x: 1.0637436, y: 0, z: 5.3302784}
+        m_Extent: {x: 17.332994, y: 0, z: 17.813997}
+      rotation: {x: 0, y: 0, z: 0, w: 1}
+      scale: {x: 1, y: 1, z: 1}
+      perAnchorNormalsAngle:
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      - 0
+      globalNormalsAngle: 0
+      flipNormals: 0
+    vertexPathUpToDate: 1
+    vertexPathMaxAngleError: 0.3
+    vertexPathMinVertexSpacing: 0.01
+    pathTransformationEnabled: 0
+    showPathBounds: 0
+    showPerSegmentBounds: 0
+    displayAnchorPoints: 1
+    displayControlPoints: 1
+    bezierHandleScale: 7.64
+    globalDisplaySettingsFoldout: 0
+    keepConstantHandleSize: 0
+    showNormalsInVertexMode: 0
+    showBezierPathInVertexMode: 0
+    showDisplayOptions: 0
+    showPathOptions: 0
+    showVertexPathDisplayOptions: 0
+    showVertexPathOptions: 1
+    showNormals: 0
+    showNormalsHelpInfo: 0
+    tabIndex: 0
+  initialized: 1
+--- !u!114 &1173081725
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1173081723}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: d12b1fe1b42884d7692049d7f6f79ee9, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  pathCreator: {fileID: 1173081724}
+  autoUpdate: 1
+  prefab: {fileID: 4033822839321833552, guid: f19b52bc2573b4e508c60232d5ba4c53, type: 2}
+  holder: {fileID: 1100876285}
+  spacing: 6.11
+--- !u!4 &1173081726
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1173081723}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1239443494
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1239443495}
+  - component: {fileID: 1239443497}
+  - component: {fileID: 1239443496}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1239443495
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1239443494}
+  m_LocalRotation: {x: 0.51114064, y: -0.5111407, z: -0.4886054, w: 0.4886054}
+  m_LocalPosition: {x: -2.3383734, y: 0.4048736, z: 23.356722}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 8
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1239443496
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1239443494}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1239443497
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1239443494}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1305567045
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1305567046}
+  - component: {fileID: 1305567048}
+  - component: {fileID: 1305567047}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1305567046
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1305567045}
+  m_LocalRotation: {x: -0.34406978, y: 0.34406978, z: -0.61775076, w: 0.61775076}
+  m_LocalPosition: {x: 15.058696, y: 0.4048736, z: 2.730334}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1305567047
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1305567045}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1305567048
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1305567045}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1413329163
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1413329164}
+  - component: {fileID: 1413329166}
+  - component: {fileID: 1413329165}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1413329164
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1413329163}
+  m_LocalRotation: {x: -0.46657854, y: 0.46657854, z: -0.5313234, w: 0.5313234}
+  m_LocalPosition: {x: 3.9528432, y: 0.4048736, z: -12.155033}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 17
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1413329165
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1413329163}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1413329166
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1413329163}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1451327457
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1451327458}
+  - component: {fileID: 1451327460}
+  - component: {fileID: 1451327459}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1451327458
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1451327457}
+  m_LocalRotation: {x: 0.7051131, y: -0.7051131, z: 0.053061392, w: -0.053061392}
+  m_LocalPosition: {x: -14.709441, y: 0.4048736, z: 0.8449825}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 13
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1451327459
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1451327457}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1451327460
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1451327457}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1489228398
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1489228399}
+  - component: {fileID: 1489228401}
+  - component: {fileID: 1489228400}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1489228399
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1489228398}
+  m_LocalRotation: {x: 0.53863406, y: -0.53863406, z: 0.4581194, w: -0.4581194}
+  m_LocalPosition: {x: 3.3699255, y: 0.4048736, z: 1.2684951}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1489228400
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1489228398}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1489228401
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1489228398}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1551300062
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1551300063}
+  - component: {fileID: 1551300065}
+  - component: {fileID: 1551300064}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1551300063
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1551300062}
+  m_LocalRotation: {x: 0.5853645, y: -0.5853645, z: 0.39667162, w: -0.39667162}
+  m_LocalPosition: {x: -1.9577849, y: 0.4048736, z: -10.917622}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 16
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1551300064
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1551300062}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1551300065
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1551300062}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1631447299
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1631447300}
+  - component: {fileID: 1631447302}
+  - component: {fileID: 1631447301}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1631447300
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1631447299}
+  m_LocalRotation: {x: 0.5621399, y: -0.56213987, z: -0.42895082, w: 0.42895082}
+  m_LocalPosition: {x: -8.37764, y: 0.4048736, z: 22.51158}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 9
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1631447301
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1631447299}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1631447302
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1631447299}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1653420824
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1653420825}
+  - component: {fileID: 1653420827}
+  - component: {fileID: 1653420826}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1653420825
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1653420824}
+  m_LocalRotation: {x: 0.47242323, y: -0.47242323, z: -0.5261334, w: 0.52613336}
+  m_LocalPosition: {x: 3.7633872, y: 0.4048736, z: 23.181543}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 7
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1653420826
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1653420824}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1653420827
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1653420824}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1726925214
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1726925215}
+  - component: {fileID: 1726925217}
+  - component: {fileID: 1726925216}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1726925215
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1726925214}
+  m_LocalRotation: {x: -0.12087492, y: 0.12087492, z: -0.6966989, w: 0.69669884}
+  m_LocalPosition: {x: 19.46735, y: 0.4048736, z: 6.836807}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1726925216
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1726925214}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1726925217
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1726925214}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1743644111
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1743644112}
+  - component: {fileID: 1743644114}
+  - component: {fileID: 1743644113}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1743644112
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1743644111}
+  m_LocalRotation: {x: -0.20450312, y: 0.20450312, z: -0.6768888, w: 0.6768888}
+  m_LocalPosition: {x: 18.56629, y: 0.4048736, z: -2.4241676}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 20
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1743644113
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1743644111}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1743644114
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1743644111}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1836065499
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1836065500}
+  - component: {fileID: 1836065502}
+  - component: {fileID: 1836065501}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1836065500
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1836065499}
+  m_LocalRotation: {x: 0.19032404, y: -0.19032404, z: -0.6810116, w: 0.6810116}
+  m_LocalPosition: {x: 17.74937, y: 0.4048736, z: 12.543003}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 4
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1836065501
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1836065499}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1836065502
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1836065499}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &1863139042
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1863139043}
+  - component: {fileID: 1863139045}
+  - component: {fileID: 1863139044}
+  m_Layer: 0
+  m_Name: Cube(Clone)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!4 &1863139043
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1863139042}
+  m_LocalRotation: {x: 0.6531901, y: -0.65319, z: 0.27081865, w: -0.27081865}
+  m_LocalPosition: {x: -12.382312, y: 0.4048736, z: -4.669839}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 1100876286}
+  m_RootOrder: 14
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!23 &1863139044
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1863139042}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1863139045
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1863139042}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}

+ 7 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Object Placement.unity.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: f9d700f5f914447f48566abe5b02d921
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 517 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Path as Prefab.unity

@@ -0,0 +1,517 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 2
+  m_OcclusionBakeSettings:
+    smallestOccluder: 5
+    smallestHole: 0.25
+    backfaceThreshold: 100
+  m_SceneGUID: 00000000000000000000000000000000
+  m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 9
+  m_Fog: 0
+  m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+  m_FogMode: 3
+  m_FogDensity: 0.01
+  m_LinearFogStart: 0
+  m_LinearFogEnd: 300
+  m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+  m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+  m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+  m_AmbientIntensity: 1
+  m_AmbientMode: 0
+  m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+  m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+  m_HaloStrength: 0.5
+  m_FlareStrength: 1
+  m_FlareFadeSpeed: 3
+  m_HaloTexture: {fileID: 0}
+  m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+  m_DefaultReflectionMode: 0
+  m_DefaultReflectionResolution: 128
+  m_ReflectionBounces: 1
+  m_ReflectionIntensity: 1
+  m_CustomReflection: {fileID: 0}
+  m_Sun: {fileID: 0}
+  m_IndirectSpecularColor: {r: 0.4465934, g: 0.49642956, b: 0.57482487, a: 1}
+  m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+  m_ObjectHideFlags: 0
+  serializedVersion: 11
+  m_GIWorkflowMode: 0
+  m_GISettings:
+    serializedVersion: 2
+    m_BounceScale: 1
+    m_IndirectOutputScale: 1
+    m_AlbedoBoost: 1
+    m_TemporalCoherenceThreshold: 1
+    m_EnvironmentLightingMode: 0
+    m_EnableBakedLightmaps: 1
+    m_EnableRealtimeLightmaps: 1
+  m_LightmapEditorSettings:
+    serializedVersion: 10
+    m_Resolution: 2
+    m_BakeResolution: 40
+    m_AtlasSize: 1024
+    m_AO: 0
+    m_AOMaxDistance: 1
+    m_CompAOExponent: 1
+    m_CompAOExponentDirect: 0
+    m_Padding: 2
+    m_LightmapParameters: {fileID: 0}
+    m_LightmapsBakeMode: 1
+    m_TextureCompression: 1
+    m_FinalGather: 0
+    m_FinalGatherFiltering: 1
+    m_FinalGatherRayCount: 256
+    m_ReflectionCompression: 2
+    m_MixedBakeMode: 2
+    m_BakeBackend: 1
+    m_PVRSampling: 1
+    m_PVRDirectSampleCount: 32
+    m_PVRSampleCount: 500
+    m_PVRBounces: 2
+    m_PVRFilterTypeDirect: 0
+    m_PVRFilterTypeIndirect: 0
+    m_PVRFilterTypeAO: 0
+    m_PVRFilteringMode: 2
+    m_PVRCulling: 1
+    m_PVRFilteringGaussRadiusDirect: 1
+    m_PVRFilteringGaussRadiusIndirect: 5
+    m_PVRFilteringGaussRadiusAO: 2
+    m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+    m_PVRFilteringAtrousPositionSigmaIndirect: 2
+    m_PVRFilteringAtrousPositionSigmaAO: 1
+    m_ShowResolutionOverlay: 1
+  m_LightingDataAsset: {fileID: 0}
+  m_UseShadowmask: 1
+--- !u!196 &4
+NavMeshSettings:
+  serializedVersion: 2
+  m_ObjectHideFlags: 0
+  m_BuildSettings:
+    serializedVersion: 2
+    agentTypeID: 0
+    agentRadius: 0.5
+    agentHeight: 2
+    agentSlope: 45
+    agentClimb: 0.4
+    ledgeDropHeight: 0
+    maxJumpAcrossDistance: 0
+    minRegionArea: 2
+    manualCellSize: 0
+    cellSize: 0.16666667
+    manualTileSize: 0
+    tileSize: 256
+    accuratePlacement: 0
+    debug:
+      m_Flags: 0
+  m_NavMeshData: {fileID: 0}
+--- !u!1 &854113292
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 854113295}
+  - component: {fileID: 854113294}
+  - component: {fileID: 854113293}
+  m_Layer: 0
+  m_Name: Spawn 1
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!23 &854113293
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 854113292}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 2100000, guid: 5c270a73328a99e439fec44a0cf3a17d, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &854113294
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 854113292}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &854113295
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 854113292}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: -6, y: 0, z: 0}
+  m_LocalScale: {x: 3.7376, y: 0.14671586, z: 3.7376}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 3
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1001367091
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1001367094}
+  - component: {fileID: 1001367093}
+  - component: {fileID: 1001367092}
+  m_Layer: 0
+  m_Name: Spawn 3
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!23 &1001367092
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1001367091}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 2100000, guid: 01763a1c279a5cd4d8f897f6b6cdbae5, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1001367093
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1001367091}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1001367094
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1001367091}
+  m_LocalRotation: {x: -0.3582922, y: -0, z: -0, w: 0.9336095}
+  m_LocalPosition: {x: 0, y: 2.6, z: 5.85}
+  m_LocalScale: {x: 3.7376, y: 0.14671586, z: 3.7376}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 5
+  m_LocalEulerAnglesHint: {x: -41.991, y: 0, z: 0}
+--- !u!1 &1170195241
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1170195244}
+  - component: {fileID: 1170195243}
+  - component: {fileID: 1170195242}
+  m_Layer: 0
+  m_Name: Spawn 2
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!23 &1170195242
+MeshRenderer:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1170195241}
+  m_Enabled: 1
+  m_CastShadows: 1
+  m_ReceiveShadows: 1
+  m_DynamicOccludee: 1
+  m_MotionVectors: 1
+  m_LightProbeUsage: 1
+  m_ReflectionProbeUsage: 1
+  m_RenderingLayerMask: 1
+  m_Materials:
+  - {fileID: 2100000, guid: 9ca80467a033e954a8b9ad8601d6f4c7, type: 2}
+  m_StaticBatchInfo:
+    firstSubMesh: 0
+    subMeshCount: 0
+  m_StaticBatchRoot: {fileID: 0}
+  m_ProbeAnchor: {fileID: 0}
+  m_LightProbeVolumeOverride: {fileID: 0}
+  m_ScaleInLightmap: 1
+  m_PreserveUVs: 0
+  m_IgnoreNormalsForChartDetection: 0
+  m_ImportantGI: 0
+  m_StitchLightmapSeams: 1
+  m_SelectedEditorRenderState: 3
+  m_MinimumChartSize: 4
+  m_AutoUVMaxDistance: 0.5
+  m_AutoUVMaxAngle: 89
+  m_LightmapParameters: {fileID: 0}
+  m_SortingLayerID: 0
+  m_SortingLayer: 0
+  m_SortingOrder: 0
+--- !u!33 &1170195243
+MeshFilter:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1170195241}
+  m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1170195244
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1170195241}
+  m_LocalRotation: {x: -0, y: -0, z: 0.480542, w: 0.87697166}
+  m_LocalPosition: {x: 6, y: 0, z: 0}
+  m_LocalScale: {x: 3.7376, y: 0.14671586, z: 3.7376}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 4
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 57.442}
+--- !u!1 &1308570505
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1308570508}
+  - component: {fileID: 1308570507}
+  - component: {fileID: 1308570506}
+  m_Layer: 0
+  m_Name: Main Camera
+  m_TagString: MainCamera
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!81 &1308570506
+AudioListener:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1308570505}
+  m_Enabled: 1
+--- !u!20 &1308570507
+Camera:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1308570505}
+  m_Enabled: 1
+  serializedVersion: 2
+  m_ClearFlags: 1
+  m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+  m_NormalizedViewPortRect:
+    serializedVersion: 2
+    x: 0
+    y: 0
+    width: 1
+    height: 1
+  near clip plane: 0.3
+  far clip plane: 1000
+  field of view: 60
+  orthographic: 0
+  orthographic size: 5
+  m_Depth: -1
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_RenderingPath: -1
+  m_TargetTexture: {fileID: 0}
+  m_TargetDisplay: 0
+  m_TargetEye: 3
+  m_HDR: 1
+  m_AllowMSAA: 1
+  m_AllowDynamicResolution: 0
+  m_ForceIntoRT: 0
+  m_OcclusionCulling: 1
+  m_StereoConvergence: 10
+  m_StereoSeparation: 0.022
+--- !u!4 &1308570508
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1308570505}
+  m_LocalRotation: {x: 0.17410469, y: -0, z: -0, w: 0.9847272}
+  m_LocalPosition: {x: 0, y: 6.41, z: -11.71}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 20.053001, y: 0, z: 0}
+--- !u!1 &1518276650
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1518276652}
+  - component: {fileID: 1518276651}
+  m_Layer: 0
+  m_Name: Spawner
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1518276651
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1518276650}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: b617cc208d0104cad9534d503ff3e1cf, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  pathPrefab: {fileID: 114462757500385858, guid: 2791553a612d84e7c9f3c0a95308376f,
+    type: 2}
+  followerPrefab: {fileID: 114548013775708692, guid: 761d600d1e80341ac97f3228771ce637,
+    type: 2}
+  spawnPoints:
+  - {fileID: 854113295}
+  - {fileID: 1170195244}
+  - {fileID: 1001367094}
+--- !u!4 &1518276652
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1518276650}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1844901808
+GameObject:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  serializedVersion: 5
+  m_Component:
+  - component: {fileID: 1844901810}
+  - component: {fileID: 1844901809}
+  m_Layer: 0
+  m_Name: Directional Light
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!108 &1844901809
+Light:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1844901808}
+  m_Enabled: 1
+  serializedVersion: 8
+  m_Type: 1
+  m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+  m_Intensity: 1
+  m_Range: 10
+  m_SpotAngle: 30
+  m_CookieSize: 10
+  m_Shadows:
+    m_Type: 2
+    m_Resolution: -1
+    m_CustomResolution: -1
+    m_Strength: 1
+    m_Bias: 0.05
+    m_NormalBias: 0.4
+    m_NearPlane: 0.2
+  m_Cookie: {fileID: 0}
+  m_DrawHalo: 0
+  m_Flare: {fileID: 0}
+  m_RenderMode: 0
+  m_CullingMask:
+    serializedVersion: 2
+    m_Bits: 4294967295
+  m_Lightmapping: 4
+  m_AreaSize: {x: 1, y: 1}
+  m_BounceIntensity: 1
+  m_ColorTemperature: 6570
+  m_UseColorTemperature: 0
+  m_ShadowRadius: 0
+  m_ShadowAngle: 0
+--- !u!4 &1844901810
+Transform:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1844901808}
+  m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+  m_LocalPosition: {x: 0, y: 3, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}

+ 7 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scenes/Path as Prefab.unity.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 7c3960531f0fd44beaacc5037d708071
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scripts.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4708a8b1933bb914e98024a2cd57b3a8
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 115 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scripts/CylinderMeshCreator.cs

@@ -0,0 +1,115 @@
+using System.Collections.Generic;
+using PathCreation.Utility;
+using UnityEngine;
+
+namespace PathCreation.Examples {
+	public class CylinderMeshCreator : PathSceneTool {
+
+		public float thickness = .15f;
+		[Range (3, 30)]
+		public int resolutionU = 10;
+		[Min (0)]
+		public float resolutionV = 20;
+
+		public Material material;
+
+		[SerializeField, HideInInspector]
+		GameObject meshHolder;
+
+		MeshFilter meshFilter;
+		MeshRenderer meshRenderer;
+		Mesh mesh;
+
+		protected override void PathUpdated () {
+			if (pathCreator != null) {
+				AssignMeshComponents ();
+				AssignMaterials ();
+				CreateMesh ();
+			}
+		}
+
+		void CreateMesh () {
+			List<Vector3> verts = new List<Vector3> ();
+			List<int> triangles = new List<int> ();
+
+			int numCircles = Mathf.Max (2, Mathf.RoundToInt (path.length * resolutionV) + 1);
+			var pathInstruction = PathCreation.EndOfPathInstruction.Stop;
+
+			for (int s = 0; s < numCircles; s++) {
+				float segmentPercent = s / (numCircles - 1f);
+				Vector3 centerPos = path.GetPointAtTime (segmentPercent, pathInstruction);
+				Vector3 norm = path.GetNormal (segmentPercent, pathInstruction);
+				Vector3 forward = path.GetDirection (segmentPercent, pathInstruction);
+				Vector3 tangentOrWhatEver = Vector3.Cross (norm, forward);
+
+				for (int currentRes = 0; currentRes < resolutionU; currentRes++) {
+					var angle = ((float) currentRes / resolutionU) * (Mathf.PI * 2.0f);
+
+					var xVal = Mathf.Sin (angle) * thickness;
+					var yVal = Mathf.Cos (angle) * thickness;
+
+					var point = (norm * xVal) + (tangentOrWhatEver * yVal) + centerPos;
+					verts.Add (point);
+
+					//! Adding the triangles
+					if (s < numCircles - 1) {
+						int startIndex = resolutionU * s;
+						triangles.Add (startIndex + currentRes);
+						triangles.Add (startIndex + (currentRes + 1) % resolutionU);
+						triangles.Add (startIndex + currentRes + resolutionU);
+
+						triangles.Add (startIndex + (currentRes + 1) % resolutionU);
+						triangles.Add (startIndex + (currentRes + 1) % resolutionU + resolutionU);
+						triangles.Add (startIndex + currentRes + resolutionU);
+					}
+
+				}
+			}
+
+			if (mesh == null) {
+				mesh = new Mesh ();
+			} else {
+				mesh.Clear ();
+			}
+
+			mesh.SetVertices (verts);
+			mesh.SetTriangles (triangles, 0);
+			mesh.RecalculateNormals ();
+
+		}
+
+		// Add MeshRenderer and MeshFilter components to this gameobject if not already attached
+		void AssignMeshComponents () {
+
+			if (meshHolder == null) {
+				meshHolder = new GameObject ("Mesh Holder");
+			}
+
+			meshHolder.transform.rotation = Quaternion.identity;
+			meshHolder.transform.position = Vector3.zero;
+			meshHolder.transform.localScale = Vector3.one;
+
+			// Ensure mesh renderer and filter components are assigned
+			if (!meshHolder.gameObject.GetComponent<MeshFilter> ()) {
+				meshHolder.gameObject.AddComponent<MeshFilter> ();
+			}
+			if (!meshHolder.GetComponent<MeshRenderer> ()) {
+				meshHolder.gameObject.AddComponent<MeshRenderer> ();
+			}
+
+			meshRenderer = meshHolder.GetComponent<MeshRenderer> ();
+			meshFilter = meshHolder.GetComponent<MeshFilter> ();
+			if (mesh == null) {
+				mesh = new Mesh ();
+			}
+			meshFilter.sharedMesh = mesh;
+		}
+
+		void AssignMaterials () {
+			if (material != null) {
+				meshRenderer.sharedMaterial = material;
+			}
+		}
+
+	}
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scripts/CylinderMeshCreator.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 977f1d9610a354cb99a2bf6640f03e8b
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scripts/Editor.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 37afd3c65f48fa94bbb5a65473466658
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 108 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scripts/Editor/PathSceneToolEditor.cs

@@ -0,0 +1,108 @@
+using UnityEngine;
+using UnityEditor;
+using PathCreation;
+
+namespace PathCreation.Examples
+{
+    [CustomEditor(typeof(PathSceneTool), true)]
+    public class PathSceneToolEditor : Editor
+    {
+        protected PathSceneTool pathTool;
+        bool isSubscribed;
+
+        public override void OnInspectorGUI()
+        {
+            using (var check = new EditorGUI.ChangeCheckScope())
+            {
+                DrawDefaultInspector();
+
+                if (check.changed)
+                {
+                    if (!isSubscribed)
+                    {
+                        TryFindPathCreator();
+                        Subscribe();
+                    }
+
+                    if (pathTool.autoUpdate)
+                    {
+                        TriggerUpdate();
+
+                    }
+                }
+            }
+
+            if (GUILayout.Button("Manual Update"))
+            {
+                if (TryFindPathCreator())
+                {
+                    TriggerUpdate();
+                    SceneView.RepaintAll();
+                }
+            }
+
+        }
+
+
+        void TriggerUpdate() {
+            if (pathTool.pathCreator != null) {
+                pathTool.TriggerUpdate();
+            }
+        }
+
+
+        protected virtual void OnPathModified()
+        {
+            if (pathTool.autoUpdate)
+            {
+                TriggerUpdate();
+            }
+        }
+
+        protected virtual void OnEnable()
+        {
+            pathTool = (PathSceneTool)target;
+            pathTool.onDestroyed += OnToolDestroyed;
+
+            if (TryFindPathCreator())
+            {
+                Subscribe();
+                TriggerUpdate();
+            }
+        }
+
+        void OnToolDestroyed() {
+            if (pathTool != null) {
+                pathTool.pathCreator.pathUpdated -= OnPathModified;
+            }
+        }
+
+ 
+        protected virtual void Subscribe()
+        {
+            if (pathTool.pathCreator != null)
+            {
+                isSubscribed = true;
+                pathTool.pathCreator.pathUpdated -= OnPathModified;
+                pathTool.pathCreator.pathUpdated += OnPathModified;
+            }
+        }
+
+        bool TryFindPathCreator()
+        {
+            // Try find a path creator in the scene, if one is not already assigned
+            if (pathTool.pathCreator == null)
+            {
+                if (pathTool.GetComponent<PathCreator>() != null)
+                {
+                    pathTool.pathCreator = pathTool.GetComponent<PathCreator>();
+                }
+                else if (FindObjectOfType<PathCreator>())
+                {
+                    pathTool.pathCreator = FindObjectOfType<PathCreator>();
+                }
+            }
+            return pathTool.pathCreator != null;
+        }
+    }
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scripts/Editor/PathSceneToolEditor.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: db8aedf6f6cf2734cb24c49646427e96
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 20 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scripts/GeneratePathExample.cs

@@ -0,0 +1,20 @@
+using UnityEngine;
+
+namespace PathCreation.Examples {
+    // Example of creating a path at runtime from a set of points.
+
+    [RequireComponent(typeof(PathCreator))]
+    public class GeneratePathExample : MonoBehaviour {
+
+        public bool closedLoop = true;
+        public Transform[] waypoints;
+
+        void Start () {
+            if (waypoints.Length > 0) {
+                // Create a new bezier path from the waypoints.
+                BezierPath bezierPath = new BezierPath (waypoints, closedLoop, PathSpace.xyz);
+                GetComponent<PathCreator> ().bezierPath = bezierPath;
+            }
+        }
+    }
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scripts/GeneratePathExample.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f417e74782fffcd40b77b0fdbe82af04
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 38 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scripts/PathFollower.cs

@@ -0,0 +1,38 @@
+using UnityEngine;
+
+namespace PathCreation.Examples
+{
+    // Moves along a path at constant speed.
+    // Depending on the end of path instruction, will either loop, reverse, or stop at the end of the path.
+    public class PathFollower : MonoBehaviour
+    {
+        public PathCreator pathCreator;
+        public EndOfPathInstruction endOfPathInstruction;
+        public float speed = 5;
+        float distanceTravelled;
+
+        void Start() {
+            if (pathCreator != null)
+            {
+                // Subscribed to the pathUpdated event so that we're notified if the path changes during the game
+                pathCreator.pathUpdated += OnPathChanged;
+            }
+        }
+
+        void Update()
+        {
+            if (pathCreator != null)
+            {
+                distanceTravelled += speed * Time.deltaTime;
+                transform.position = pathCreator.path.GetPointAtDistance(distanceTravelled, endOfPathInstruction);
+                transform.rotation = pathCreator.path.GetRotationAtDistance(distanceTravelled, endOfPathInstruction);
+            }
+        }
+
+        // If the path changes during the game, update the distance travelled so that the follower's position on the new path
+        // is as close as possible to its position on the old path
+        void OnPathChanged() {
+            distanceTravelled = pathCreator.path.GetClosestDistanceAlongPath(transform.position);
+        }
+    }
+}

+ 11 - 0
ActionTowerDefense/Assets/PathCreator/Examples/Scripts/PathFollower.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 33aabe1a2dec93349b06e6e5dc51bc06
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.