import pathcreator
This commit is contained in:
parent
4ccf346241
commit
513b0a1eb3
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c78921add991a914aa4263c80d69a9d6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fded9f896ea32473eb30ae61b640a176
|
||||
folderAsset: yes
|
||||
timeCreated: 1519645413
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 76c2f3171eae9954aa317277dbffd478
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 366e41d4e3408334aad31e48f28757e4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bd0de63ca5c52504a8d2063418a326c3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 804ddb43548540a4ca3b0a534a75c4b3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 05aed72a972059e45a62e31c2bb60fc4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "PathCreatorEditor",
|
||||
"references": [
|
||||
"PathCreator"
|
||||
],
|
||||
"optionalUnityReferences": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": []
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 92ee438f32d811247a22ca14bf2a3fe0
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c62dae0f992c5174a951248617cc5720
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2b76edb14a39ed944b9c906e5f1d3aaa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
|
@ -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:
|
|
@ -0,0 +1,3 @@
|
|||
namespace PathCreation {
|
||||
public enum EndOfPathInstruction {Loop, Reverse, Stop};
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c0d7fa70c03166e4180909b6e5d546c7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 46d5e8d803e252f4499b52e657f8e1a2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 194e1b7893dcbf940a71eb507d8b10f3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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:
|
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 19547029ffb83484e90d00c182104817
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,3 @@
|
|||
namespace PathCreation {
|
||||
public enum PathSpace {xyz, xy, xz};
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 407af8f85a5bae449bce4730c5d97d1a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 223183313f20d4049a397d83fab3151e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"name": "PathCreator"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 626070ea3273cb844a310aa4f53b31fa
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4c55bdfe2cdafc04ba5f909d4f1f192b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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:
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 096bae1d1ed960d4bb7605dce06767c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5505526f3c472e8499fa7ce169410ace
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4f9b1508dc64040469b4b1ee117d27a9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 35fab21375bf12f4b96eba4dafa4ad30
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7f53e212088d741abad12e1f2315eee7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e7b865996e4d342a39bbea59a2e43a53
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 856133338e5935c4ea7215ea837b00da
|
||||
folderAsset: yes
|
||||
timeCreated: 1546380202
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ba68311e0a74e694fbd8f64185d03175
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 69561553b86bde34da494d1ffed3ba45
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5c270a73328a99e439fec44a0cf3a17d
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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}
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d5b3a558a1e7f4a4182b166bb2f27cf7
|
||||
timeCreated: 1519840206
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 407e3de4fbbcf4a99b17bf5aac2d28d8
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9ca80467a033e954a8b9ad8601d6f4c7
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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}
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 01763a1c279a5cd4d8f897f6b6cdbae5
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
|
@ -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:
|
|
@ -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}
|
|
@ -0,0 +1,10 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c1d8d882244c5344fa86a8fd23246f81
|
||||
timeCreated: 1519840206
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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}
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b5df4735192845740bd11076dc9cdc99
|
||||
timeCreated: 1546381442
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3331696fd1c6e4ce399332471e58fe60
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f19b52bc2573b4e508c60232d5ba4c53
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 761d600d1e80341ac97f3228771ce637
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2791553a612d84e7c9f3c0a95308376f
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cb2e1e8aa0d44489c8d332b91c9a4202
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7fa8a76a6a31dba43b3f224aa4c8ef31
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c1e712ad623461e418f182144cf61384
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3145d476fb2c7f242875d23b77320de4
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f9d700f5f914447f48566abe5b02d921
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7c3960531f0fd44beaacc5037d708071
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8f020cfa1fb7ded47926b050b82adbe6
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4708a8b1933bb914e98024a2cd57b3a8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 37afd3c65f48fa94bbb5a65473466658
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: db8aedf6f6cf2734cb24c49646427e96
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f417e74782fffcd40b77b0fdbe82af04
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 33aabe1a2dec93349b06e6e5dc51bc06
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d12b1fe1b42884d7692049d7f6f79ee9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 83aca5399f4e71c44b5d6c1314b5b95f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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
Loading…
Reference in New Issue