Merge branch 'feature/path-spline' into 'main'

Feature/path spline

Closes #44

See merge request kernel-panic/revival!45
This commit is contained in:
Cinder Foster-Smith 2021-03-15 16:13:41 +00:00
commit 9cedec4d74
110 changed files with 12073 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,43 @@
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, then depthFor3DSpace will be used as distance from scene camera.
/// </summary>
public static Vector3 GetMouseWorldPosition(PathSpace space, float depthFor3DSpace = 10)
{
Ray mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
Vector3 worldMouse = mouseRay.GetPoint(depthFor3DSpace);
// Mouse can only move on XY plane
if (space == PathSpace.xy)
{
float zDir = mouseRay.direction.z;
if (zDir != 0)
{
float dstToXYPlane = Mathf.Abs(mouseRay.origin.z / zDir);
worldMouse = mouseRay.GetPoint(dstToXYPlane);
}
}
// Mouse can only move on XZ plane
else if (space == PathSpace.xz)
{
float yDir = mouseRay.direction.y;
if (yDir != 0)
{
float dstToXZPlane = Mathf.Abs(mouseRay.origin.y / yDir);
worldMouse = mouseRay.GetPoint(dstToXZPlane);
}
}
return worldMouse;
}
}
}

View File

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

View File

@ -0,0 +1,237 @@
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.up;
Camera cam = Camera.current;
if (cam != null)
{
if (cam.orthographic)
{
lookForward= -cam.transform.forward;
}
else
{
lookForward = (cam.transform.position - position);
}
}
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];
}
}
}

View File

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

View File

@ -0,0 +1,215 @@
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 premCamIsOrtho;
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 != premCamIsOrtho)
{
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;
premCamIsOrtho = 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 percentBetweenVertices = dstToPointOnLine / (points[closestPolyLineSegmentIndex] - points[closestPolyLineSegmentIndex + 1]).magnitude;
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;
}
}
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,736 @@
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) {
// insert new point at same dst from scene camera as the point that comes before it (for a 3d path)
float dstCamToEndpoint = (Camera.current.transform.position - bezierPath[bezierPath.NumPoints - 1]).magnitude;
Vector3 newPathPoint = MouseUtility.GetMouseWorldPosition (bezierPath.Space, dstCamToEndpoint);
newPathPoint = MathUtility.InverseTransformPoint (newPathPoint, creator.transform, bezierPath.Space);
Undo.RecordObject (creator, "Add segment");
if (e.control || e.command) {
bezierPath.AddSegmentToStart (newPathPoint);
} else {
bezierPath.AddSegmentToEnd (newPathPoint);
}
}
}
}
// 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 ();
if (pathMouseInfo.mouseDstToLine < segmentSelectDistanceThreshold) {
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
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,678 @@
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
/// <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) {
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
}
}

View File

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

View File

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

View File

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

View File

@ -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
}
}

View File

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

View File

@ -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));
}
}
}

View File

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

View File

@ -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
}
}

View File

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

View File

@ -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 ();
}
}
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,345 @@
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 = 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) {
TimeOnPathData data = CalculateClosestPointOnPathData (worldPoint);
return Vector3.Lerp (GetPoint (data.previousIndex), GetPoint (data.nextIndex), data.percentBetweenIndices);
}
/// 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) {
TimeOnPathData data = CalculateClosestPointOnPathData (worldPoint);
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) {
TimeOnPathData data = CalculateClosestPointOnPathData (worldPoint);
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 worldPoint) {
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 (worldPoint, GetPoint (i), GetPoint (nextI));
float sqrDst = (worldPoint - closestPointOnSegment).sqrMagnitude;
if (sqrDst < minSqrDst) {
minSqrDst = sqrDst;
closestPoint = closestPointOnSegment;
closestSegmentIndexA = i;
closestSegmentIndexB = nextI;
}
}
float closestSegmentLength = (GetPoint (closestSegmentIndexA) - GetPoint (closestSegmentIndexB)).magnitude;
float t = (closestPoint - GetPoint (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
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
}
}
}

View File

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

View File

@ -0,0 +1,162 @@
using System.Collections.Generic;
using UnityEngine;
namespace PathCreation.Utility {
public static class MathUtility {
static PosRotScale LockTransformToSpace (Transform t, PathSpace space) {
var original = new PosRotScale (t);
if (space == PathSpace.xy) {
t.eulerAngles = new Vector3 (0, 0, t.eulerAngles.z);
t.position = new Vector3 (t.position.x, t.position.y, 0);
} else if (space == PathSpace.xz) {
t.eulerAngles = new Vector3 (0, t.eulerAngles.y, 0);
t.position = new Vector3 (t.position.x, 0, t.position.z);
}
//float maxScale = Mathf.Max (t.localScale.x * t.parent.localScale.x, t.localScale.y * t.parent.localScale.y, t.localScale.z * t.parent.localScale.z);
float maxScale = Mathf.Max (t.lossyScale.x, t.lossyScale.y, t.lossyScale.z);
t.localScale = Vector3.one * maxScale;
return original;
}
public static Vector3 TransformPoint (Vector3 p, Transform t, PathSpace space) {
var original = LockTransformToSpace (t, space);
Vector3 transformedPoint = t.TransformPoint (p);
original.SetTransform (t);
return transformedPoint;
}
public static Vector3 InverseTransformPoint (Vector3 p, Transform t, PathSpace space) {
var original = LockTransformToSpace (t, space);
Vector3 transformedPoint = t.InverseTransformPoint (p);
original.SetTransform (t);
return transformedPoint;
}
public static Vector3 TransformVector (Vector3 p, Transform t, PathSpace space) {
var original = LockTransformToSpace (t, space);
Vector3 transformedPoint = t.TransformVector (p);
original.SetTransform (t);
return transformedPoint;
}
public static Vector3 InverseTransformVector (Vector3 p, Transform t, PathSpace space) {
var original = LockTransformToSpace (t, space);
Vector3 transformedPoint = t.InverseTransformVector (p);
original.SetTransform (t);
return transformedPoint;
}
public static Vector3 TransformDirection (Vector3 p, Transform t, PathSpace space) {
var original = LockTransformToSpace (t, space);
Vector3 transformedPoint = t.TransformDirection (p);
original.SetTransform (t);
return transformedPoint;
}
public static Vector3 InverseTransformDirection (Vector3 p, Transform t, PathSpace space) {
var original = LockTransformToSpace (t, space);
Vector3 transformedPoint = t.InverseTransformDirection (p);
original.SetTransform (t);
return transformedPoint;
}
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;
}
class PosRotScale {
public readonly Vector3 position;
public readonly Quaternion rotation;
public readonly Vector3 scale;
public PosRotScale (Transform t) {
this.position = t.position;
this.rotation = t.rotation;
this.scale = t.localScale;
}
public void SetTransform (Transform t) {
t.position = position;
t.rotation = rotation;
t.localScale = scale;
}
}
}
}

View File

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

View File

@ -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();
}
}
}

View File

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

View File

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

View File

@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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}

View File

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

View File

@ -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}

View File

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

View File

@ -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}

View File

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

View File

@ -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}

View File

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

View File

@ -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}

View File

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

View File

@ -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}

View File

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

BIN
game/Assets/PathCreator/Examples/Materials/Road Texture.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,74 @@
fileFormatVersion: 2
guid: eef7def8a6d89134284369bbe0145515
timeCreated: 1546381451
licenseType: Store
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:

View File

@ -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}

View File

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

View File

@ -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}

View File

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

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

@ -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

View File

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

View File

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

View File

@ -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}

View File

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

View File

@ -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}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -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}

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

@ -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;
}
}
}

View File

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

View File

@ -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;
}
}
}
}

View File

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

View File

@ -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);
}
}
}

View File

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

View File

@ -0,0 +1,46 @@
using PathCreation;
using UnityEngine;
namespace PathCreation.Examples {
[ExecuteInEditMode]
public class PathPlacer : PathSceneTool {
public GameObject prefab;
public GameObject holder;
public float spacing = 3;
const float minSpacing = .1f;
void Generate () {
if (pathCreator != null && prefab != null && holder != null) {
DestroyObjects ();
VertexPath path = pathCreator.path;
spacing = Mathf.Max(minSpacing, spacing);
float dst = 0;
while (dst < path.length) {
Vector3 point = path.GetPointAtDistance (dst);
Quaternion rot = path.GetRotationAtDistance (dst);
Instantiate (prefab, point, rot, holder.transform);
dst += spacing;
}
}
}
void DestroyObjects () {
int numChildren = holder.transform.childCount;
for (int i = numChildren - 1; i >= 0; i--) {
DestroyImmediate (holder.transform.GetChild (i).gameObject, false);
}
}
protected override void PathUpdated () {
if (pathCreator != null) {
Generate ();
}
}
}
}

View File

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

View File

@ -0,0 +1,31 @@
using UnityEngine;
namespace PathCreation.Examples
{
[ExecuteInEditMode]
public abstract class PathSceneTool : MonoBehaviour
{
public event System.Action onDestroyed;
public PathCreator pathCreator;
public bool autoUpdate = true;
protected VertexPath path {
get {
return pathCreator.path;
}
}
public void TriggerUpdate() {
PathUpdated();
}
protected virtual void OnDestroy() {
if (onDestroyed != null) {
onDestroyed();
}
}
protected abstract void PathUpdated();
}
}

View File

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

View File

@ -0,0 +1,25 @@
using System.Collections;
using System.Collections.Generic;
using PathCreation;
using UnityEngine;
namespace PathCreation.Examples {
public class PathSpawner : MonoBehaviour {
public PathCreator pathPrefab;
public PathFollower followerPrefab;
public Transform[] spawnPoints;
void Start () {
foreach (Transform t in spawnPoints) {
var path = Instantiate (pathPrefab, t.position, t.rotation);
var follower = Instantiate (followerPrefab);
follower.pathCreator = path;
path.transform.parent = t;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More