Initial commit
41
Library/PackageCache/com.unity.2d.path@2.1.0/CHANGELOG.md
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Changelog
|
||||
|
||||
## [2.1.0] - 2020-11-16
|
||||
###Changed
|
||||
- Minor version bump due to change in required Unity version
|
||||
|
||||
## [2.0.6] - 2020-07-17
|
||||
### Changed
|
||||
- Snapping Control Points and Tangents use Global Move Snap settings.
|
||||
|
||||
## [2.0.5] - 2020-05-08
|
||||
### Changed
|
||||
- Added return for Path tool usage change.
|
||||
|
||||
## [2.0.4] - 2019-10-27
|
||||
### Fixed
|
||||
- Added missing meta file
|
||||
|
||||
## [2.0.3] - 2019-10-02
|
||||
### Fixed
|
||||
- Removed resources
|
||||
|
||||
## [2.0.2] - 2019-07-24
|
||||
### Added
|
||||
- Add related test packages
|
||||
|
||||
## [2.0.1] - 2019-07-13
|
||||
### Changed
|
||||
- Mark package to support Unity 2019.3.0a10 onwards.
|
||||
|
||||
## [2.0.0] - 2019-06-19
|
||||
### Changed.
|
||||
- Stable Version.
|
||||
|
||||
## [1.0.0-preview.3] - 2019-06-14
|
||||
### Fixed
|
||||
- Fix undo on select point.
|
||||
|
||||
## [1.0.0-preview.1] - 2019-04-22
|
||||
### Added
|
||||
- Initial Version.
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c1b975030cb01fa4fb63b07dc5584b12
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,3 @@
|
|||
# Introduction
|
||||
|
||||
2D Path provides a set of tools to edit polygons and b-splines in custom EditorWindow and the SceneView.
|
8
Library/PackageCache/com.unity.2d.path@2.1.0/Editor.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ebb15515f9c03364089baa7120b54453
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c69472069f4ff5e4b9db75c91210288f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,223 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public static class BezierUtility
|
||||
{
|
||||
static Vector3[] s_TempPoints = new Vector3[3];
|
||||
|
||||
public static Vector3 BezierPoint(Vector3 startPosition, Vector3 startTangent, Vector3 endTangent, Vector3 endPosition, float t)
|
||||
{
|
||||
float s = 1.0f - t;
|
||||
return startPosition * s * s * s + startTangent * s * s * t * 3.0f + endTangent * s * t * t * 3.0f + endPosition * t * t * t;
|
||||
}
|
||||
|
||||
public static Vector3 ClosestPointOnCurve(Vector3 point, Vector3 startPosition, Vector3 endPosition, Vector3 startTangent, Vector3 endTangent, out float t)
|
||||
{
|
||||
Vector3 startToEnd = endPosition - startPosition;
|
||||
Vector3 startToTangent = (startTangent - startPosition);
|
||||
Vector3 endToTangent = (endTangent - endPosition);
|
||||
|
||||
float sqrError = 0.001f;
|
||||
|
||||
if (Colinear(startToTangent, startToEnd, sqrError) && Colinear(endToTangent, startToEnd, sqrError))
|
||||
return ClosestPointToSegment(point, startPosition, endPosition, out t);
|
||||
|
||||
Vector3 leftStartPosition;
|
||||
Vector3 leftEndPosition;
|
||||
Vector3 leftStartTangent;
|
||||
Vector3 leftEndTangent;
|
||||
|
||||
Vector3 rightStartPosition;
|
||||
Vector3 rightEndPosition;
|
||||
Vector3 rightStartTangent;
|
||||
Vector3 rightEndTangent;
|
||||
|
||||
float leftStartT = 0f;
|
||||
float leftEndT = 0.5f;
|
||||
float rightStartT = 0.5f;
|
||||
float rightEndT = 1f;
|
||||
|
||||
SplitBezier(0.5f, startPosition, endPosition, startTangent, endTangent,
|
||||
out leftStartPosition, out leftEndPosition, out leftStartTangent, out leftEndTangent,
|
||||
out rightStartPosition, out rightEndPosition, out rightStartTangent, out rightEndTangent);
|
||||
|
||||
Vector3 pointLeft = ClosestPointOnCurveIterative(point, leftStartPosition, leftEndPosition, leftStartTangent, leftEndTangent, sqrError, ref leftStartT, ref leftEndT);
|
||||
Vector3 pointRight = ClosestPointOnCurveIterative(point, rightStartPosition, rightEndPosition, rightStartTangent, rightEndTangent, sqrError, ref rightStartT, ref rightEndT);
|
||||
|
||||
if ((point - pointLeft).sqrMagnitude < (point - pointRight).sqrMagnitude)
|
||||
{
|
||||
t = leftStartT;
|
||||
return pointLeft;
|
||||
}
|
||||
|
||||
t = rightStartT;
|
||||
return pointRight;
|
||||
}
|
||||
|
||||
public static Vector3 ClosestPointOnCurveFast(Vector3 point, Vector3 startPosition, Vector3 endPosition, Vector3 startTangent, Vector3 endTangent, out float t)
|
||||
{
|
||||
float sqrError = 0.001f;
|
||||
float startT = 0f;
|
||||
float endT = 1f;
|
||||
|
||||
Vector3 closestPoint = ClosestPointOnCurveIterative(point, startPosition, endPosition, startTangent, endTangent, sqrError, ref startT, ref endT);
|
||||
|
||||
t = startT;
|
||||
|
||||
return closestPoint;
|
||||
}
|
||||
|
||||
private static Vector3 ClosestPointOnCurveIterative(Vector3 point, Vector3 startPosition, Vector3 endPosition, Vector3 startTangent, Vector3 endTangent, float sqrError, ref float startT, ref float endT)
|
||||
{
|
||||
while ((startPosition - endPosition).sqrMagnitude > sqrError)
|
||||
{
|
||||
Vector3 startToEnd = endPosition - startPosition;
|
||||
Vector3 startToTangent = (startTangent - startPosition);
|
||||
Vector3 endToTangent = (endTangent - endPosition);
|
||||
|
||||
if (Colinear(startToTangent, startToEnd, sqrError) && Colinear(endToTangent, startToEnd, sqrError))
|
||||
{
|
||||
float t;
|
||||
Vector3 closestPoint = ClosestPointToSegment(point, startPosition, endPosition, out t);
|
||||
t *= (endT - startT);
|
||||
startT += t;
|
||||
endT -= t;
|
||||
return closestPoint;
|
||||
}
|
||||
|
||||
Vector3 leftStartPosition;
|
||||
Vector3 leftEndPosition;
|
||||
Vector3 leftStartTangent;
|
||||
Vector3 leftEndTangent;
|
||||
|
||||
Vector3 rightStartPosition;
|
||||
Vector3 rightEndPosition;
|
||||
Vector3 rightStartTangent;
|
||||
Vector3 rightEndTangent;
|
||||
|
||||
SplitBezier(0.5f, startPosition, endPosition, startTangent, endTangent,
|
||||
out leftStartPosition, out leftEndPosition, out leftStartTangent, out leftEndTangent,
|
||||
out rightStartPosition, out rightEndPosition, out rightStartTangent, out rightEndTangent);
|
||||
|
||||
s_TempPoints[0] = leftStartPosition;
|
||||
s_TempPoints[1] = leftStartTangent;
|
||||
s_TempPoints[2] = leftEndTangent;
|
||||
|
||||
float sqrDistanceLeft = SqrDistanceToPolyLine(point, s_TempPoints);
|
||||
|
||||
s_TempPoints[0] = rightEndPosition;
|
||||
s_TempPoints[1] = rightEndTangent;
|
||||
s_TempPoints[2] = rightStartTangent;
|
||||
|
||||
float sqrDistanceRight = SqrDistanceToPolyLine(point, s_TempPoints);
|
||||
|
||||
if (sqrDistanceLeft < sqrDistanceRight)
|
||||
{
|
||||
startPosition = leftStartPosition;
|
||||
endPosition = leftEndPosition;
|
||||
startTangent = leftStartTangent;
|
||||
endTangent = leftEndTangent;
|
||||
|
||||
endT -= (endT - startT) * 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
startPosition = rightStartPosition;
|
||||
endPosition = rightEndPosition;
|
||||
startTangent = rightStartTangent;
|
||||
endTangent = rightEndTangent;
|
||||
|
||||
startT += (endT - startT) * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
return endPosition;
|
||||
}
|
||||
|
||||
public static void SplitBezier(float t, Vector3 startPosition, Vector3 endPosition, Vector3 startRightTangent, Vector3 endLeftTangent,
|
||||
out Vector3 leftStartPosition, out Vector3 leftEndPosition, out Vector3 leftStartTangent, out Vector3 leftEndTangent,
|
||||
out Vector3 rightStartPosition, out Vector3 rightEndPosition, out Vector3 rightStartTangent, out Vector3 rightEndTangent)
|
||||
{
|
||||
Vector3 tangent0 = (startRightTangent - startPosition);
|
||||
Vector3 tangent1 = (endLeftTangent - endPosition);
|
||||
Vector3 tangentEdge = (endLeftTangent - startRightTangent);
|
||||
|
||||
Vector3 tangentPoint0 = startPosition + tangent0 * t;
|
||||
Vector3 tangentPoint1 = endPosition + tangent1 * (1f - t);
|
||||
Vector3 tangentEdgePoint = startRightTangent + tangentEdge * t;
|
||||
|
||||
Vector3 newTangent0 = tangentPoint0 + (tangentEdgePoint - tangentPoint0) * t;
|
||||
Vector3 newTangent1 = tangentPoint1 + (tangentEdgePoint - tangentPoint1) * (1f - t);
|
||||
Vector3 newTangentEdge = newTangent1 - newTangent0;
|
||||
|
||||
Vector3 bezierPoint = newTangent0 + newTangentEdge * t;
|
||||
|
||||
leftStartPosition = startPosition;
|
||||
leftEndPosition = bezierPoint;
|
||||
leftStartTangent = tangentPoint0;
|
||||
leftEndTangent = newTangent0;
|
||||
|
||||
rightStartPosition = bezierPoint;
|
||||
rightEndPosition = endPosition;
|
||||
rightStartTangent = newTangent1;
|
||||
rightEndTangent = tangentPoint1;
|
||||
}
|
||||
|
||||
private static Vector3 ClosestPointToSegment(Vector3 point, Vector3 segmentStart, Vector3 segmentEnd, out float t)
|
||||
{
|
||||
Vector3 relativePoint = point - segmentStart;
|
||||
Vector3 segment = (segmentEnd - segmentStart);
|
||||
Vector3 segmentDirection = segment.normalized;
|
||||
float length = segment.magnitude;
|
||||
|
||||
float dot = Vector3.Dot(relativePoint, segmentDirection);
|
||||
|
||||
if (dot <= 0f)
|
||||
dot = 0f;
|
||||
else if (dot >= length)
|
||||
dot = length;
|
||||
|
||||
t = dot / length;
|
||||
|
||||
return segmentStart + segment * t;
|
||||
}
|
||||
|
||||
private static float SqrDistanceToPolyLine(Vector3 point, Vector3[] points)
|
||||
{
|
||||
float minDistance = float.MaxValue;
|
||||
|
||||
for (int i = 0; i < points.Length - 1; ++i)
|
||||
{
|
||||
float distance = SqrDistanceToSegment(point, points[i], points[i + 1]);
|
||||
|
||||
if (distance < minDistance)
|
||||
minDistance = distance;
|
||||
}
|
||||
|
||||
return minDistance;
|
||||
}
|
||||
|
||||
private static float SqrDistanceToSegment(Vector3 point, Vector3 segmentStart, Vector3 segmentEnd)
|
||||
{
|
||||
Vector3 relativePoint = point - segmentStart;
|
||||
Vector3 segment = (segmentEnd - segmentStart);
|
||||
Vector3 segmentDirection = segment.normalized;
|
||||
float length = segment.magnitude;
|
||||
|
||||
float dot = Vector3.Dot(relativePoint, segmentDirection);
|
||||
|
||||
if (dot <= 0f)
|
||||
return (point - segmentStart).sqrMagnitude;
|
||||
else if (dot >= length)
|
||||
return (point - segmentEnd).sqrMagnitude;
|
||||
|
||||
return Vector3.Cross(relativePoint, segmentDirection).sqrMagnitude;
|
||||
}
|
||||
|
||||
private static bool Colinear(Vector3 v1, Vector3 v2, float error = 0.0001f)
|
||||
{
|
||||
return Mathf.Abs(v1.x * v2.y - v1.y * v2.x + v1.x * v2.z - v1.z * v2.x + v1.y * v2.z - v1.z * v2.y) < error;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7539b6de552451b409d8d2f8657251c6
|
||||
timeCreated: 1505799796
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public enum TangentMode
|
||||
{
|
||||
Linear = 0,
|
||||
Continuous = 1,
|
||||
Broken = 2
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct TangentCache
|
||||
{
|
||||
public Vector3 leftTangent;
|
||||
public Vector3 rightTangent;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct ControlPoint
|
||||
{
|
||||
public Vector3 position;
|
||||
public Vector3 localLeftTangent;
|
||||
public Vector3 localRightTangent;
|
||||
public TangentMode tangentMode;
|
||||
public TangentCache continuousCache;
|
||||
public TangentCache brokenCache;
|
||||
public bool mirrorLeft;
|
||||
|
||||
public Vector3 leftTangent
|
||||
{
|
||||
get { return localLeftTangent + position; }
|
||||
set { localLeftTangent = value - position; }
|
||||
}
|
||||
|
||||
public Vector3 rightTangent
|
||||
{
|
||||
get { return localRightTangent + position; }
|
||||
set { localRightTangent = value - position; }
|
||||
}
|
||||
|
||||
public void StoreTangents()
|
||||
{
|
||||
if (tangentMode == TangentMode.Continuous)
|
||||
{
|
||||
continuousCache.leftTangent = localLeftTangent;
|
||||
continuousCache.rightTangent = localRightTangent;
|
||||
}
|
||||
else if (tangentMode == TangentMode.Broken)
|
||||
{
|
||||
brokenCache.leftTangent = localLeftTangent;
|
||||
brokenCache.rightTangent = localRightTangent;
|
||||
}
|
||||
}
|
||||
|
||||
public void RestoreTangents()
|
||||
{
|
||||
if (tangentMode == TangentMode.Continuous)
|
||||
{
|
||||
localLeftTangent = continuousCache.leftTangent;
|
||||
localRightTangent = continuousCache.rightTangent;
|
||||
}
|
||||
else if (tangentMode == TangentMode.Broken)
|
||||
{
|
||||
localLeftTangent = brokenCache.leftTangent;
|
||||
localRightTangent = brokenCache.rightTangent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6e22e7e2cce9e9346a8291ccf224487a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,147 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
[Serializable]
|
||||
public class EditablePath : IEditablePath
|
||||
{
|
||||
[SerializeField]
|
||||
private ShapeType m_ShapeType;
|
||||
[SerializeField]
|
||||
private IndexedSelection m_Selection = new IndexedSelection();
|
||||
[SerializeField]
|
||||
private List<ControlPoint> m_ControlPoints = new List<ControlPoint>();
|
||||
[SerializeField]
|
||||
private bool m_IsOpenEnded;
|
||||
private Matrix4x4 m_LocalToWorldMatrix = Matrix4x4.identity;
|
||||
private Matrix4x4 m_WorldToLocalMatrix = Matrix4x4.identity;
|
||||
private Vector3 m_Forward = Vector3.forward;
|
||||
private Vector3 m_Up = Vector3.up;
|
||||
private Vector3 m_Right = Vector3.right;
|
||||
|
||||
public ShapeType shapeType
|
||||
{
|
||||
get { return m_ShapeType; }
|
||||
set { m_ShapeType = value; }
|
||||
}
|
||||
|
||||
public IUndoObject undoObject { get; set; }
|
||||
|
||||
public Matrix4x4 localToWorldMatrix
|
||||
{
|
||||
get { return m_LocalToWorldMatrix; }
|
||||
set
|
||||
{
|
||||
m_LocalToWorldMatrix = value;
|
||||
m_WorldToLocalMatrix = value.inverse;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 forward
|
||||
{
|
||||
get { return m_Forward; }
|
||||
set { m_Forward = value; }
|
||||
}
|
||||
|
||||
public Vector3 up
|
||||
{
|
||||
get { return m_Up; }
|
||||
set { m_Up = value; }
|
||||
}
|
||||
|
||||
public Vector3 right
|
||||
{
|
||||
get { return m_Right; }
|
||||
set { m_Right = value; }
|
||||
}
|
||||
|
||||
public Matrix4x4 worldToLocalMatrix
|
||||
{
|
||||
get { return m_WorldToLocalMatrix; }
|
||||
}
|
||||
|
||||
public bool isOpenEnded
|
||||
{
|
||||
get
|
||||
{
|
||||
if (pointCount < 3)
|
||||
return true;
|
||||
|
||||
return m_IsOpenEnded;
|
||||
}
|
||||
set { m_IsOpenEnded = value; }
|
||||
}
|
||||
|
||||
public ISelection<int> selection
|
||||
{
|
||||
get { return m_Selection; }
|
||||
}
|
||||
|
||||
public int pointCount
|
||||
{
|
||||
get { return m_ControlPoints.Count; }
|
||||
}
|
||||
|
||||
public ControlPoint GetPoint(int index)
|
||||
{
|
||||
return TransformPoint(localToWorldMatrix, m_ControlPoints[index]);
|
||||
}
|
||||
|
||||
public void SetPoint(int index, ControlPoint controlPoint)
|
||||
{
|
||||
m_ControlPoints[index] = TransformPoint(worldToLocalMatrix, controlPoint);
|
||||
}
|
||||
|
||||
public void AddPoint(ControlPoint controlPoint)
|
||||
{
|
||||
m_ControlPoints.Insert(pointCount, TransformPoint(worldToLocalMatrix, controlPoint));
|
||||
}
|
||||
|
||||
public void InsertPoint(int index, ControlPoint controlPoint)
|
||||
{
|
||||
m_ControlPoints.Insert(index, TransformPoint(worldToLocalMatrix, controlPoint));
|
||||
}
|
||||
|
||||
public void RemovePoint(int index)
|
||||
{
|
||||
m_ControlPoints.RemoveAt(index);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_ControlPoints.Clear();
|
||||
}
|
||||
|
||||
private ControlPoint TransformPoint(Matrix4x4 transformMatrix, ControlPoint controlPoint)
|
||||
{
|
||||
if (transformMatrix == Matrix4x4.identity)
|
||||
return controlPoint;
|
||||
|
||||
var newControlPoint = new ControlPoint()
|
||||
{
|
||||
position = transformMatrix.MultiplyPoint3x4(controlPoint.position),
|
||||
tangentMode = controlPoint.tangentMode,
|
||||
continuousCache = controlPoint.continuousCache,
|
||||
brokenCache = controlPoint.brokenCache,
|
||||
mirrorLeft = controlPoint.mirrorLeft
|
||||
};
|
||||
|
||||
newControlPoint.rightTangent = transformMatrix.MultiplyPoint3x4(controlPoint.rightTangent);
|
||||
newControlPoint.leftTangent = transformMatrix.MultiplyPoint3x4(controlPoint.leftTangent);
|
||||
|
||||
return newControlPoint;
|
||||
}
|
||||
|
||||
public bool Select(ISelector<Vector3> selector)
|
||||
{
|
||||
var changed = false;
|
||||
|
||||
for (var i = 0; i < pointCount; ++i)
|
||||
changed |= selection.Select(i, selector.Select(GetPoint(i).position));
|
||||
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cc93dba6e70bb8044a38eeb19db22669
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,259 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public class EditablePathController : IEditablePathController
|
||||
{
|
||||
private ISnapping<Vector3> m_Snapping = new Snapping();
|
||||
|
||||
public IEditablePath editablePath { get; set; }
|
||||
public IEditablePath closestEditablePath { get { return editablePath; } }
|
||||
|
||||
public ISnapping<Vector3> snapping
|
||||
{
|
||||
get { return m_Snapping; }
|
||||
set { m_Snapping = value; }
|
||||
}
|
||||
|
||||
public bool enableSnapping { get; set; }
|
||||
|
||||
public void RegisterUndo(string name)
|
||||
{
|
||||
if (editablePath.undoObject != null)
|
||||
editablePath.undoObject.RegisterUndo(name);
|
||||
}
|
||||
|
||||
public void ClearSelection()
|
||||
{
|
||||
editablePath.selection.Clear();
|
||||
}
|
||||
|
||||
public void SelectPoint(int index, bool select)
|
||||
{
|
||||
editablePath.selection.Select(index, select);
|
||||
}
|
||||
|
||||
public void CreatePoint(int index, Vector3 position)
|
||||
{
|
||||
ClearSelection();
|
||||
|
||||
if (editablePath.shapeType == ShapeType.Polygon)
|
||||
{
|
||||
editablePath.InsertPoint(index + 1, new ControlPoint() { position = position });
|
||||
}
|
||||
else if (editablePath.shapeType == ShapeType.Spline)
|
||||
{
|
||||
var nextIndex = NextIndex(index);
|
||||
var currentPoint = editablePath.GetPoint(index);
|
||||
var nextPoint = editablePath.GetPoint(nextIndex);
|
||||
|
||||
float t;
|
||||
var closestPoint = BezierUtility.ClosestPointOnCurve(
|
||||
position,
|
||||
currentPoint.position,
|
||||
nextPoint.position,
|
||||
GetRightTangentPosition(index),
|
||||
GetLeftTangentPosition(nextIndex),
|
||||
out t);
|
||||
|
||||
Vector3 leftStartPosition;
|
||||
Vector3 leftEndPosition;
|
||||
Vector3 leftStartTangent;
|
||||
Vector3 leftEndTangent;
|
||||
|
||||
Vector3 rightStartPosition;
|
||||
Vector3 rightEndPosition;
|
||||
Vector3 rightStartTangent;
|
||||
Vector3 rightEndTangent;
|
||||
|
||||
BezierUtility.SplitBezier(t, currentPoint.position, nextPoint.position, GetRightTangentPosition(index), GetLeftTangentPosition(nextIndex),
|
||||
out leftStartPosition, out leftEndPosition, out leftStartTangent, out leftEndTangent,
|
||||
out rightStartPosition, out rightEndPosition, out rightStartTangent, out rightEndTangent);
|
||||
|
||||
var newPointIndex = index + 1;
|
||||
var newPoint = new ControlPoint()
|
||||
{
|
||||
position = closestPoint,
|
||||
leftTangent = leftEndTangent,
|
||||
rightTangent = rightStartTangent,
|
||||
tangentMode = TangentMode.Continuous
|
||||
};
|
||||
|
||||
currentPoint.rightTangent = leftStartTangent;
|
||||
nextPoint.leftTangent = rightEndTangent;
|
||||
|
||||
if (currentPoint.tangentMode == TangentMode.Linear && nextPoint.tangentMode == TangentMode.Linear)
|
||||
{
|
||||
newPoint.tangentMode = TangentMode.Linear;
|
||||
newPoint.localLeftTangent = Vector3.zero;
|
||||
newPoint.localRightTangent = Vector3.zero;
|
||||
currentPoint.localRightTangent = Vector3.zero;
|
||||
nextPoint.localLeftTangent = Vector3.zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentPoint.tangentMode == TangentMode.Linear)
|
||||
currentPoint.tangentMode = TangentMode.Broken;
|
||||
|
||||
if (nextPoint.tangentMode == TangentMode.Linear)
|
||||
nextPoint.tangentMode = TangentMode.Broken;
|
||||
}
|
||||
|
||||
editablePath.SetPoint(index, currentPoint);
|
||||
editablePath.SetPoint(nextIndex, nextPoint);
|
||||
editablePath.InsertPoint(newPointIndex, newPoint);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveSelectedPoints()
|
||||
{
|
||||
var minPointCount = editablePath.isOpenEnded ? 2 : 3;
|
||||
|
||||
if (editablePath.pointCount > minPointCount)
|
||||
{
|
||||
var indices = editablePath.selection.elements.OrderByDescending( i => i);
|
||||
|
||||
foreach (var index in indices)
|
||||
if (editablePath.pointCount > minPointCount)
|
||||
editablePath.RemovePoint(index);
|
||||
|
||||
ClearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveSelectedPoints(Vector3 delta)
|
||||
{
|
||||
delta = Vector3.ProjectOnPlane(delta, editablePath.forward);
|
||||
|
||||
for (var i = 0; i < editablePath.pointCount; ++i)
|
||||
{
|
||||
if (editablePath.selection.Contains(i))
|
||||
{
|
||||
var controlPoint = editablePath.GetPoint(i);
|
||||
controlPoint.position += delta;
|
||||
editablePath.SetPoint(i, controlPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveEdge(int index, Vector3 delta)
|
||||
{
|
||||
if (editablePath.isOpenEnded && index == editablePath.pointCount - 1)
|
||||
return;
|
||||
|
||||
var controlPoint = editablePath.GetPoint(index);
|
||||
controlPoint.position += delta;
|
||||
editablePath.SetPoint(index, controlPoint);
|
||||
controlPoint = NextControlPoint(index);
|
||||
controlPoint.position += delta;
|
||||
editablePath.SetPoint(NextIndex(index), controlPoint);
|
||||
}
|
||||
|
||||
public void SetLeftTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedRightTangent, TangentMode cachedTangentMode)
|
||||
{
|
||||
var controlPoint = editablePath.GetPoint(index);
|
||||
controlPoint.tangentMode = cachedTangentMode;
|
||||
controlPoint.leftTangent = position;
|
||||
controlPoint.mirrorLeft = false;
|
||||
|
||||
if (setToLinear)
|
||||
{
|
||||
controlPoint.leftTangent = controlPoint.position;
|
||||
controlPoint.rightTangent = cachedRightTangent;
|
||||
}
|
||||
else if (controlPoint.tangentMode == TangentMode.Continuous || mirror)
|
||||
{
|
||||
var magnitude = controlPoint.localRightTangent.magnitude;
|
||||
|
||||
if (mirror)
|
||||
magnitude = controlPoint.localLeftTangent.magnitude;
|
||||
|
||||
controlPoint.localRightTangent = magnitude * -controlPoint.localLeftTangent.normalized;
|
||||
}
|
||||
|
||||
editablePath.SetPoint(index, controlPoint);
|
||||
editablePath.UpdateTangentMode(index);
|
||||
}
|
||||
|
||||
public void SetRightTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedLeftTangent, TangentMode cachedTangentMode)
|
||||
{
|
||||
var controlPoint = editablePath.GetPoint(index);
|
||||
controlPoint.tangentMode = cachedTangentMode;
|
||||
controlPoint.rightTangent = position;
|
||||
controlPoint.mirrorLeft = true;
|
||||
|
||||
if (setToLinear)
|
||||
{
|
||||
controlPoint.rightTangent = controlPoint.position;
|
||||
controlPoint.leftTangent = cachedLeftTangent;
|
||||
}
|
||||
else if (controlPoint.tangentMode == TangentMode.Continuous || mirror)
|
||||
{
|
||||
var magnitude = controlPoint.localLeftTangent.magnitude;
|
||||
|
||||
if (mirror)
|
||||
magnitude = controlPoint.localRightTangent.magnitude;
|
||||
|
||||
controlPoint.localLeftTangent = magnitude * -controlPoint.localRightTangent.normalized;
|
||||
}
|
||||
|
||||
editablePath.SetPoint(index, controlPoint);
|
||||
editablePath.UpdateTangentMode(index);
|
||||
}
|
||||
|
||||
public void ClearClosestPath() { }
|
||||
public void AddClosestPath(float distance) { }
|
||||
|
||||
private Vector3 GetLeftTangentPosition(int index)
|
||||
{
|
||||
var isLinear = Mathf.Approximately(editablePath.GetPoint(index).localLeftTangent.sqrMagnitude, 0f);
|
||||
|
||||
if (isLinear)
|
||||
{
|
||||
var position = editablePath.GetPoint(index).position;
|
||||
var prevPosition = PrevControlPoint(index).position;
|
||||
|
||||
return (1f / 3f) * (prevPosition - position) + position;
|
||||
}
|
||||
|
||||
return editablePath.GetPoint(index).leftTangent;
|
||||
}
|
||||
|
||||
private Vector3 GetRightTangentPosition(int index)
|
||||
{
|
||||
var isLinear = Mathf.Approximately(editablePath.GetPoint(index).localRightTangent.sqrMagnitude, 0f);
|
||||
|
||||
if (isLinear)
|
||||
{
|
||||
var position = editablePath.GetPoint(index).position;
|
||||
var nextPosition = NextControlPoint(index).position;
|
||||
|
||||
return (1f / 3f) * (nextPosition - position) + position;
|
||||
}
|
||||
|
||||
return editablePath.GetPoint(index).rightTangent;
|
||||
}
|
||||
|
||||
private int NextIndex(int index)
|
||||
{
|
||||
return EditablePathUtility.Mod(index + 1, editablePath.pointCount);
|
||||
}
|
||||
|
||||
private ControlPoint NextControlPoint(int index)
|
||||
{
|
||||
return editablePath.GetPoint(NextIndex(index));
|
||||
}
|
||||
|
||||
private int PrevIndex(int index)
|
||||
{
|
||||
return EditablePathUtility.Mod(index - 1, editablePath.pointCount);
|
||||
}
|
||||
|
||||
private ControlPoint PrevControlPoint(int index)
|
||||
{
|
||||
return editablePath.GetPoint(PrevIndex(index));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e097fcf51266c654f8f8ef2c431a91d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,275 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public static class EditablePathExtensions
|
||||
{
|
||||
public static Polygon ToPolygon(this IEditablePath path)
|
||||
{
|
||||
var polygon = new Polygon()
|
||||
{
|
||||
isOpenEnded = path.isOpenEnded,
|
||||
points = new Vector3[path.pointCount]
|
||||
};
|
||||
|
||||
for (var i = 0; i < path.pointCount; ++i)
|
||||
polygon.points[i] = path.GetPoint(i).position;
|
||||
|
||||
return polygon;
|
||||
}
|
||||
|
||||
public static Spline ToSpline(this IEditablePath path)
|
||||
{
|
||||
var count = path.pointCount * 3;
|
||||
|
||||
if (path.isOpenEnded)
|
||||
count -= 2;
|
||||
|
||||
var spline = new Spline()
|
||||
{
|
||||
isOpenEnded = path.isOpenEnded,
|
||||
points = new Vector3[count]
|
||||
};
|
||||
|
||||
for (var i = 0; i < path.pointCount; ++i)
|
||||
{
|
||||
var point = path.GetPoint(i);
|
||||
|
||||
spline.points[i*3] = point.position;
|
||||
|
||||
if (i * 3 + 1 < count)
|
||||
{
|
||||
var nextIndex = EditablePathUtility.Mod(i+1, path.pointCount);
|
||||
|
||||
spline.points[i*3 + 1] = path.CalculateRightTangent(i);
|
||||
spline.points[i*3 + 2] = path.CalculateLeftTangent(nextIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return spline;
|
||||
}
|
||||
|
||||
public static Vector3 CalculateLocalLeftTangent(this IEditablePath path, int index)
|
||||
{
|
||||
return path.CalculateLeftTangent(index) - path.GetPoint(index).position;
|
||||
}
|
||||
|
||||
public static Vector3 CalculateLeftTangent(this IEditablePath path, int index)
|
||||
{
|
||||
var point = path.GetPoint(index);
|
||||
var isTangentLinear = point.localLeftTangent == Vector3.zero;
|
||||
var isEndpoint = path.isOpenEnded && index == 0;
|
||||
var tangent = point.leftTangent;
|
||||
|
||||
if (isEndpoint)
|
||||
return point.position;
|
||||
|
||||
if (isTangentLinear)
|
||||
{
|
||||
var prevPoint = path.GetPrevPoint(index);
|
||||
var v = prevPoint.position - point.position;
|
||||
tangent = point.position + v.normalized * (v.magnitude / 3f);
|
||||
}
|
||||
|
||||
return tangent;
|
||||
}
|
||||
|
||||
public static Vector3 CalculateLocalRightTangent(this IEditablePath path, int index)
|
||||
{
|
||||
return path.CalculateRightTangent(index) - path.GetPoint(index).position;
|
||||
}
|
||||
|
||||
public static Vector3 CalculateRightTangent(this IEditablePath path, int index)
|
||||
{
|
||||
var point = path.GetPoint(index);
|
||||
var isTangentLinear = point.localRightTangent == Vector3.zero;
|
||||
var isEndpoint = path.isOpenEnded && index == path.pointCount - 1;
|
||||
var tangent = point.rightTangent;
|
||||
|
||||
if (isEndpoint)
|
||||
return point.position;
|
||||
|
||||
if (isTangentLinear)
|
||||
{
|
||||
var nextPoint = path.GetNextPoint(index);
|
||||
var v = nextPoint.position - point.position;
|
||||
tangent = point.position + v.normalized * (v.magnitude / 3f);
|
||||
}
|
||||
|
||||
return tangent;
|
||||
}
|
||||
|
||||
public static ControlPoint GetPrevPoint(this IEditablePath path, int index)
|
||||
{
|
||||
return path.GetPoint(EditablePathUtility.Mod(index - 1, path.pointCount));
|
||||
}
|
||||
|
||||
public static ControlPoint GetNextPoint(this IEditablePath path, int index)
|
||||
{
|
||||
return path.GetPoint(EditablePathUtility.Mod(index + 1, path.pointCount));
|
||||
}
|
||||
|
||||
public static void UpdateTangentMode(this IEditablePath path, int index)
|
||||
{
|
||||
var localToWorldMatrix = path.localToWorldMatrix;
|
||||
path.localToWorldMatrix = Matrix4x4.identity;
|
||||
|
||||
var controlPoint = path.GetPoint(index);
|
||||
var isLeftTangentLinear = controlPoint.localLeftTangent == Vector3.zero;
|
||||
var isRightTangentLinear = controlPoint.localRightTangent == Vector3.zero;
|
||||
|
||||
if (isLeftTangentLinear && isRightTangentLinear)
|
||||
controlPoint.tangentMode = TangentMode.Linear;
|
||||
else if (isLeftTangentLinear || isRightTangentLinear)
|
||||
controlPoint.tangentMode = TangentMode.Broken;
|
||||
else if (controlPoint.tangentMode != TangentMode.Continuous)
|
||||
controlPoint.tangentMode = TangentMode.Broken;
|
||||
|
||||
controlPoint.StoreTangents();
|
||||
path.SetPoint(index, controlPoint);
|
||||
path.localToWorldMatrix = localToWorldMatrix;
|
||||
}
|
||||
|
||||
public static void UpdateTangentsFromMode(this IEditablePath path)
|
||||
{
|
||||
const float kEpsilon = 0.001f;
|
||||
|
||||
var localToWorldMatrix = path.localToWorldMatrix;
|
||||
path.localToWorldMatrix = Matrix4x4.identity;
|
||||
|
||||
for (var i = 0; i < path.pointCount; ++i)
|
||||
{
|
||||
var controlPoint = path.GetPoint(i);
|
||||
|
||||
if (controlPoint.tangentMode == TangentMode.Linear)
|
||||
{
|
||||
controlPoint.localLeftTangent = Vector3.zero;
|
||||
controlPoint.localRightTangent = Vector3.zero;
|
||||
}
|
||||
else if (controlPoint.tangentMode == TangentMode.Broken)
|
||||
{
|
||||
var isLeftEndpoint = path.isOpenEnded && i == 0;
|
||||
var prevPoint = path.GetPrevPoint(i);
|
||||
var nextPoint = path.GetNextPoint(i);
|
||||
|
||||
var liniarLeftPosition = (prevPoint.position - controlPoint.position) / 3f;
|
||||
var isLeftTangentLinear = isLeftEndpoint || (controlPoint.localLeftTangent - liniarLeftPosition).sqrMagnitude < kEpsilon;
|
||||
|
||||
if (isLeftTangentLinear)
|
||||
controlPoint.localLeftTangent = Vector3.zero;
|
||||
|
||||
var isRightEndpoint = path.isOpenEnded && i == path.pointCount-1;
|
||||
var liniarRightPosition = (nextPoint.position - controlPoint.position) / 3f;
|
||||
var isRightTangentLinear = isRightEndpoint || (controlPoint.localRightTangent - liniarRightPosition).sqrMagnitude < kEpsilon;
|
||||
|
||||
if (isRightTangentLinear)
|
||||
controlPoint.localRightTangent = Vector3.zero;
|
||||
|
||||
if (isLeftTangentLinear && isRightTangentLinear)
|
||||
controlPoint.tangentMode = TangentMode.Linear;
|
||||
}
|
||||
else if (controlPoint.tangentMode == TangentMode.Continuous)
|
||||
{
|
||||
//TODO: ensure tangent continuity
|
||||
}
|
||||
|
||||
controlPoint.StoreTangents();
|
||||
path.SetPoint(i, controlPoint);
|
||||
}
|
||||
|
||||
path.localToWorldMatrix = localToWorldMatrix;
|
||||
}
|
||||
|
||||
public static void SetTangentMode(this IEditablePath path, int index, TangentMode tangentMode)
|
||||
{
|
||||
var localToWorldMatrix = path.localToWorldMatrix;
|
||||
path.localToWorldMatrix = Matrix4x4.identity;
|
||||
|
||||
var controlPoint = path.GetPoint(index);
|
||||
var isEndpoint = path.isOpenEnded && (index == 0 || index == path.pointCount - 1);
|
||||
var oldTangentMode = controlPoint.tangentMode;
|
||||
|
||||
controlPoint.tangentMode = tangentMode;
|
||||
controlPoint.RestoreTangents();
|
||||
|
||||
if (tangentMode == TangentMode.Linear)
|
||||
{
|
||||
controlPoint.localLeftTangent = Vector3.zero;
|
||||
controlPoint.localRightTangent = Vector3.zero;
|
||||
}
|
||||
else if (tangentMode == TangentMode.Continuous && !isEndpoint)
|
||||
{
|
||||
var isLeftLinear = controlPoint.localLeftTangent == Vector3.zero;
|
||||
var isRightLinear = controlPoint.localRightTangent == Vector3.zero;
|
||||
var tangentDotProduct = Vector3.Dot(controlPoint.localLeftTangent.normalized, controlPoint.localRightTangent.normalized);
|
||||
var isContinous = tangentDotProduct < 0f && (tangentDotProduct + 1) < 0.001f;
|
||||
var isLinear = isLeftLinear && isRightLinear;
|
||||
|
||||
if ((isLinear || oldTangentMode == TangentMode.Broken) && !isContinous)
|
||||
{
|
||||
var prevPoint = path.GetPrevPoint(index);
|
||||
var nextPoint = path.GetNextPoint(index);
|
||||
var vLeft = prevPoint.position - controlPoint.position;
|
||||
var vRight = nextPoint.position - controlPoint.position;
|
||||
var rightDirection = Vector3.Cross(Vector3.Cross(vLeft, vRight), vLeft.normalized + vRight.normalized).normalized;
|
||||
var scale = 1f / 3f;
|
||||
|
||||
if (isLeftLinear)
|
||||
controlPoint.localLeftTangent = vLeft.magnitude * scale * -rightDirection;
|
||||
else
|
||||
controlPoint.localLeftTangent = controlPoint.localLeftTangent.magnitude * -rightDirection;
|
||||
|
||||
if (isRightLinear)
|
||||
controlPoint.localRightTangent = vRight.magnitude * scale * rightDirection;
|
||||
else
|
||||
controlPoint.localRightTangent = controlPoint.localRightTangent.magnitude * rightDirection;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var isLeftLinear = controlPoint.localLeftTangent == Vector3.zero;
|
||||
var isRightLinear = controlPoint.localRightTangent == Vector3.zero;
|
||||
|
||||
if (isLeftLinear || isRightLinear)
|
||||
{
|
||||
if (isLeftLinear)
|
||||
controlPoint.localLeftTangent = path.CalculateLocalLeftTangent(index);
|
||||
|
||||
if (isRightLinear)
|
||||
controlPoint.localRightTangent = path.CalculateLocalRightTangent(index);
|
||||
}
|
||||
}
|
||||
|
||||
controlPoint.StoreTangents();
|
||||
path.SetPoint(index, controlPoint);
|
||||
path.localToWorldMatrix = localToWorldMatrix;
|
||||
}
|
||||
|
||||
public static void MirrorTangent(this IEditablePath path, int index)
|
||||
{
|
||||
var localToWorldMatrix = path.localToWorldMatrix;
|
||||
path.localToWorldMatrix = Matrix4x4.identity;
|
||||
|
||||
var controlPoint = path.GetPoint(index);
|
||||
|
||||
if (controlPoint.tangentMode == TangentMode.Linear)
|
||||
return;
|
||||
|
||||
if (!Mathf.Approximately((controlPoint.localLeftTangent + controlPoint.localRightTangent).sqrMagnitude, 0f))
|
||||
{
|
||||
if (controlPoint.mirrorLeft)
|
||||
controlPoint.localLeftTangent = -controlPoint.localRightTangent;
|
||||
else
|
||||
controlPoint.localRightTangent = -controlPoint.localLeftTangent;
|
||||
|
||||
controlPoint.StoreTangents();
|
||||
path.SetPoint(index, controlPoint);
|
||||
}
|
||||
|
||||
path.localToWorldMatrix = localToWorldMatrix;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 118640352bf706b49aa5ece0cf51b03c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,14 @@
|
|||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public class EditablePathUtility
|
||||
{
|
||||
public static int Mod(int x, int m)
|
||||
{
|
||||
int r = x % m;
|
||||
return r < 0 ? r + m : r;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 136ca6dbbd8b9704cb676d8e400f8096
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,24 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public interface IEditablePath : ISelectable<Vector3>
|
||||
{
|
||||
ShapeType shapeType { get; set; }
|
||||
IUndoObject undoObject { get; set; }
|
||||
ISelection<int> selection { get; }
|
||||
Matrix4x4 localToWorldMatrix { get; set; }
|
||||
Vector3 forward { get; set; }
|
||||
Vector3 up { get; set; }
|
||||
Vector3 right { get; set; }
|
||||
bool isOpenEnded { get; set; }
|
||||
int pointCount { get; }
|
||||
ControlPoint GetPoint(int index);
|
||||
void SetPoint(int index, ControlPoint controlPoint);
|
||||
void AddPoint(ControlPoint controlPoint);
|
||||
void InsertPoint(int index, ControlPoint controlPoint);
|
||||
void RemovePoint(int index);
|
||||
void Clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5db033e7b440e254688b2fcca87e6a59
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public interface IEditablePathController
|
||||
{
|
||||
IEditablePath editablePath { get; set; }
|
||||
IEditablePath closestEditablePath { get; }
|
||||
ISnapping<Vector3> snapping { get; set; }
|
||||
bool enableSnapping { get; set; }
|
||||
void RegisterUndo(string name);
|
||||
void ClearSelection();
|
||||
void SelectPoint(int index, bool select);
|
||||
void CreatePoint(int index, Vector3 position);
|
||||
void RemoveSelectedPoints();
|
||||
void MoveSelectedPoints(Vector3 delta);
|
||||
void MoveEdge(int index, Vector3 delta);
|
||||
void SetLeftTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedRightTangent, TangentMode cachedTangentMode);
|
||||
void SetRightTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedLeftTangent, TangentMode cachedTangentMode);
|
||||
void ClearClosestPath();
|
||||
void AddClosestPath(float distance);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2416be64a5db15c4eb742e5f086682c3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,10 @@
|
|||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public interface ISnapping<T>
|
||||
{
|
||||
T Snap(T value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f15c4dfafb6d6d544ab56d8cfca74d07
|
||||
timeCreated: 1505113416
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public interface IUndoObject
|
||||
{
|
||||
void RegisterUndo(string name);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 55ba72d694e736b428394820f9ca8f24
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,153 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public class MultipleEditablePathController : IEditablePathController
|
||||
{
|
||||
private IEditablePathController m_Controller = new EditablePathController();
|
||||
private List<IEditablePath> m_Paths = new List<IEditablePath>();
|
||||
private float m_ClosestDistance = float.MaxValue;
|
||||
private IEditablePath m_ClosestPath;
|
||||
|
||||
public IEditablePath editablePath
|
||||
{
|
||||
get { return m_Controller.editablePath; }
|
||||
set { m_Controller.editablePath = value; }
|
||||
}
|
||||
|
||||
public IEditablePath closestEditablePath { get; private set; }
|
||||
|
||||
public ISnapping<Vector3> snapping
|
||||
{
|
||||
get { return m_Controller.snapping; }
|
||||
set { m_Controller.snapping = value; }
|
||||
}
|
||||
|
||||
public bool enableSnapping
|
||||
{
|
||||
get { return m_Controller.enableSnapping; }
|
||||
set { m_Controller.enableSnapping = value; }
|
||||
}
|
||||
|
||||
public void ClearPaths()
|
||||
{
|
||||
m_Paths.Clear();
|
||||
}
|
||||
|
||||
public void AddPath(IEditablePath path)
|
||||
{
|
||||
if (!m_Paths.Contains(path))
|
||||
m_Paths.Add(path);
|
||||
}
|
||||
|
||||
public void RemovePath(IEditablePath path)
|
||||
{
|
||||
m_Paths.Remove(path);
|
||||
}
|
||||
|
||||
public void RegisterUndo(string name)
|
||||
{
|
||||
var current = editablePath;
|
||||
|
||||
ForEach((s) =>
|
||||
{
|
||||
editablePath = s;
|
||||
m_Controller.RegisterUndo(name);
|
||||
});
|
||||
|
||||
editablePath = current;
|
||||
}
|
||||
|
||||
public void ClearSelection()
|
||||
{
|
||||
var current = editablePath;
|
||||
|
||||
ForEach((s) =>
|
||||
{
|
||||
editablePath = s;
|
||||
m_Controller.ClearSelection();
|
||||
});
|
||||
|
||||
editablePath = current;
|
||||
}
|
||||
|
||||
public void SelectPoint(int index, bool select)
|
||||
{
|
||||
m_Controller.SelectPoint(index, select);
|
||||
}
|
||||
|
||||
public void CreatePoint(int index, Vector3 position)
|
||||
{
|
||||
m_Controller.CreatePoint(index, position);
|
||||
}
|
||||
|
||||
public void RemoveSelectedPoints()
|
||||
{
|
||||
var current = editablePath;
|
||||
|
||||
ForEach((s) =>
|
||||
{
|
||||
editablePath = s;
|
||||
m_Controller.RemoveSelectedPoints();
|
||||
});
|
||||
|
||||
editablePath = current;
|
||||
}
|
||||
|
||||
public void MoveSelectedPoints(Vector3 delta)
|
||||
{
|
||||
var current = editablePath;
|
||||
|
||||
ForEach((s) =>
|
||||
{
|
||||
editablePath = s;
|
||||
m_Controller.MoveSelectedPoints(delta);
|
||||
});
|
||||
|
||||
editablePath = current;
|
||||
}
|
||||
|
||||
public void MoveEdge(int index, Vector3 delta)
|
||||
{
|
||||
m_Controller.MoveEdge(index, delta);
|
||||
}
|
||||
|
||||
public void SetLeftTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedRightTangent, TangentMode cachedTangentMode)
|
||||
{
|
||||
m_Controller.SetLeftTangent(index, position, setToLinear, mirror, cachedRightTangent, cachedTangentMode);
|
||||
}
|
||||
|
||||
public void SetRightTangent(int index, Vector3 position, bool setToLinear, bool mirror, Vector3 cachedLeftTangent, TangentMode cachedTangentMode)
|
||||
{
|
||||
m_Controller.SetRightTangent(index, position, setToLinear, mirror, cachedLeftTangent, cachedTangentMode);
|
||||
}
|
||||
|
||||
public void ClearClosestPath()
|
||||
{
|
||||
m_ClosestDistance = float.MaxValue;
|
||||
closestEditablePath = null;
|
||||
}
|
||||
|
||||
public void AddClosestPath(float distance)
|
||||
{
|
||||
if (distance <= m_ClosestDistance)
|
||||
{
|
||||
m_ClosestDistance = distance;
|
||||
closestEditablePath = editablePath;
|
||||
}
|
||||
}
|
||||
|
||||
private void ForEach(Action<IEditablePath> action)
|
||||
{
|
||||
foreach(var path in m_Paths)
|
||||
{
|
||||
if (path == null)
|
||||
continue;
|
||||
|
||||
action(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4e9b894eff389bc4b914e86801e4cb25
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,21 @@
|
|||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public class Snapping : ISnapping<Vector3>
|
||||
{
|
||||
public Vector3 Snap(Vector3 position)
|
||||
{
|
||||
return new Vector3(
|
||||
Snap(position.x, EditorSnapSettings.move.x),
|
||||
Snap(position.y, EditorSnapSettings.move.y),
|
||||
position.z);
|
||||
}
|
||||
|
||||
private float Snap(float value, float snap)
|
||||
{
|
||||
return Mathf.Round(value / snap) * snap;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 729f75e79f7b4da458ab89bf1f36dc90
|
||||
timeCreated: 1505113416
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 47fb61e2873922c4893faa7eff277f25
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,2 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
[assembly: InternalsVisibleTo("Unity.2D.SpriteShape.Editor")]
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b8de732c98460ec4ca63677f37beb1e8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public class GenericScriptablePath<T> : ScriptablePath
|
||||
{
|
||||
[SerializeField]
|
||||
private List<T> m_Data = new List<T>();
|
||||
|
||||
public T[] data
|
||||
{
|
||||
get { return m_Data.ToArray(); }
|
||||
set
|
||||
{
|
||||
if (value.Length != pointCount)
|
||||
throw new Exception("Custom data count does not match control point count");
|
||||
|
||||
m_Data.Clear();
|
||||
m_Data.AddRange(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
|
||||
m_Data.Clear();
|
||||
}
|
||||
|
||||
public override void AddPoint(ControlPoint controlPoint)
|
||||
{
|
||||
base.AddPoint(controlPoint);
|
||||
|
||||
m_Data.Add(Create());
|
||||
}
|
||||
|
||||
public override void InsertPoint(int index, ControlPoint controlPoint)
|
||||
{
|
||||
base.InsertPoint(index, controlPoint);
|
||||
|
||||
m_Data.Insert(index, Create());
|
||||
}
|
||||
|
||||
public override void RemovePoint(int index)
|
||||
{
|
||||
base.RemovePoint(index);
|
||||
|
||||
Destroy(m_Data[index]);
|
||||
|
||||
m_Data.RemoveAt(index);
|
||||
}
|
||||
|
||||
public T GetData(int index)
|
||||
{
|
||||
return m_Data[index];
|
||||
}
|
||||
|
||||
public void SetData(int index, T data)
|
||||
{
|
||||
m_Data[index] = data;
|
||||
}
|
||||
|
||||
protected virtual T Create()
|
||||
{
|
||||
return Activator.CreateInstance<T>();
|
||||
}
|
||||
|
||||
protected virtual void Destroy(T data) { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 91ab30a448166b74e99d488f537bfc67
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,120 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.EditorTools;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public class GenericScriptablePathInspector<U,T> : ScriptablePathInspector where U : ScriptableData<T>
|
||||
{
|
||||
private List<U> m_DataObjects = new List<U>();
|
||||
private List<U> m_SelectedDataObjects = new List<U>();
|
||||
private Editor m_CachedEditor = null;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
PrepareDataObjects();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
DestroyDataObjects();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
DoCustomDataInspector();
|
||||
}
|
||||
|
||||
protected void DoCustomDataInspector()
|
||||
{
|
||||
PrepareDataObjects();
|
||||
|
||||
if (m_SelectedDataObjects.Count > 0)
|
||||
{
|
||||
CreateCachedEditor(m_SelectedDataObjects.ToArray(), null, ref m_CachedEditor);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
m_CachedEditor.OnInspectorGUI();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
SetDataObjects();
|
||||
}
|
||||
}
|
||||
|
||||
private void PrepareDataObjects()
|
||||
{
|
||||
var elementCount = 0;
|
||||
|
||||
m_SelectedDataObjects.Clear();
|
||||
|
||||
foreach(var path in paths)
|
||||
elementCount += path.pointCount;
|
||||
|
||||
while (m_DataObjects.Count < elementCount)
|
||||
CreateDataObject();
|
||||
|
||||
var index = 0;
|
||||
foreach(var path in paths)
|
||||
{
|
||||
var genericPath = path as GenericScriptablePath<T>;
|
||||
var customDataArray = genericPath.data;
|
||||
var length = customDataArray.Length;
|
||||
|
||||
for (var i = 0; i < length; ++i)
|
||||
{
|
||||
var dataObject = m_DataObjects[index + i];
|
||||
dataObject.data = customDataArray[i];
|
||||
|
||||
if (path.selection.Contains(i))
|
||||
{
|
||||
dataObject.owner = path.owner;
|
||||
dataObject.index = i;
|
||||
m_SelectedDataObjects.Add(dataObject);
|
||||
}
|
||||
}
|
||||
|
||||
index += length;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDataObjects()
|
||||
{
|
||||
var index = 0;
|
||||
foreach(var path in paths)
|
||||
{
|
||||
var genericPath = path as GenericScriptablePath<T>;
|
||||
var customDataArray = genericPath.data;
|
||||
var length = customDataArray.Length;
|
||||
|
||||
for (var i = 0; i < length; ++i)
|
||||
customDataArray[i] = m_DataObjects[index + i].data;
|
||||
|
||||
genericPath.data = customDataArray;
|
||||
|
||||
index += length;
|
||||
}
|
||||
}
|
||||
|
||||
private U CreateDataObject()
|
||||
{
|
||||
var dataObject = ScriptableObject.CreateInstance<U>();
|
||||
m_DataObjects.Add(dataObject);
|
||||
return dataObject;
|
||||
}
|
||||
|
||||
private void DestroyDataObjects()
|
||||
{
|
||||
foreach (var customDataObject in m_DataObjects)
|
||||
DestroyImmediate(customDataObject);
|
||||
|
||||
m_DataObjects.Clear();
|
||||
m_SelectedDataObjects.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d8d7f8780c69f9742b827ffd638225fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,123 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.EditorTools;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public abstract class PathComponentEditor<T> : Editor where T : ScriptablePath
|
||||
{
|
||||
private static class Contents
|
||||
{
|
||||
public static readonly GUIContent snappingLabel = new GUIContent("Snapping", "Snap points using the snap settings");
|
||||
}
|
||||
|
||||
private Editor m_CachedEditor = null;
|
||||
|
||||
// Returns true on Changed.
|
||||
internal bool DoEditButtonChecked<U>(GUIContent icon, string label) where U : PathEditorTool<T>
|
||||
{
|
||||
const float kButtonWidth = 33;
|
||||
const float kButtonHeight = 23;
|
||||
const float k_SpaceBetweenLabelAndButton = 5;
|
||||
var buttonStyle = new GUIStyle("EditModeSingleButton");
|
||||
|
||||
var rect = EditorGUILayout.GetControlRect(true, kButtonHeight, buttonStyle);
|
||||
var buttonRect = new Rect(rect.xMin + EditorGUIUtility.labelWidth, rect.yMin, kButtonWidth, kButtonHeight);
|
||||
|
||||
var labelContent = new GUIContent(label);
|
||||
var labelSize = GUI.skin.label.CalcSize(labelContent);
|
||||
|
||||
var labelRect = new Rect(
|
||||
buttonRect.xMax + k_SpaceBetweenLabelAndButton,
|
||||
rect.yMin + (rect.height - labelSize.y) * .5f,
|
||||
labelSize.x,
|
||||
rect.height);
|
||||
|
||||
bool hasChanged = false;
|
||||
using (new EditorGUI.DisabledGroupScope(!EditorToolManager.IsAvailable<U>()))
|
||||
{
|
||||
using (var check = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
var isActive = GUI.Toggle(buttonRect, EditorToolManager.IsActiveTool<U>(), icon, buttonStyle);
|
||||
|
||||
GUI.Label(labelRect, label);
|
||||
|
||||
if (check.changed)
|
||||
{
|
||||
if (isActive)
|
||||
EditorTools.EditorTools.SetActiveTool<U>();
|
||||
else
|
||||
EditorTools.EditorTools.RestorePreviousTool();
|
||||
hasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hasChanged;
|
||||
}
|
||||
|
||||
protected void DoEditButton<U>(GUIContent icon, string label) where U : PathEditorTool<T>
|
||||
{
|
||||
DoEditButtonChecked<U>(icon, label);
|
||||
}
|
||||
|
||||
protected void DoPathInspector<U>() where U : PathEditorTool<T>
|
||||
{
|
||||
if (EditorToolManager.IsActiveTool<U>() && EditorToolManager.IsAvailable<U>())
|
||||
{
|
||||
var paths = EditorToolManager.GetEditorTool<U>().paths;
|
||||
|
||||
CreateCachedEditor(paths, null, ref m_CachedEditor);
|
||||
|
||||
if (m_CachedEditor == null) //Needed to avoid a nullref on exiting playmode
|
||||
return;
|
||||
|
||||
using (var check = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
m_CachedEditor.OnInspectorGUI();
|
||||
|
||||
if (check.changed)
|
||||
EditorToolManager.GetEditorTool<U>().SetShapes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void DoSnappingInspector<U>() where U : PathEditorTool<T>
|
||||
{
|
||||
if (EditorToolManager.IsActiveTool<U>() && EditorToolManager.IsAvailable<U>())
|
||||
{
|
||||
var tool = EditorToolManager.GetEditorTool<U>();
|
||||
tool.enableSnapping = EditorGUILayout.Toggle(Contents.snappingLabel, tool.enableSnapping);
|
||||
}
|
||||
}
|
||||
|
||||
protected void DoOpenEndedInspector<U>(SerializedProperty isOpenEndedProperty) where U : PathEditorTool<T>
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
using (var check = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
EditorGUILayout.PropertyField(isOpenEndedProperty);
|
||||
|
||||
if (check.changed)
|
||||
{
|
||||
if (EditorToolManager.IsActiveTool<U>() && EditorToolManager.IsAvailable<U>())
|
||||
{
|
||||
var paths = EditorToolManager.GetEditorTool<U>().paths;
|
||||
|
||||
foreach (var path in paths)
|
||||
{
|
||||
path.undoObject.RegisterUndo("Set Open Ended");
|
||||
path.isOpenEnded = isOpenEndedProperty.boolValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 79c3c0b6ebc836f438b76a34f04dd076
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,494 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.EditorTools;
|
||||
using UnityEditor.U2D.Path.GUIFramework;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public static class PathEditorToolContents
|
||||
{
|
||||
internal static readonly GUIContent shapeToolIcon = IconContent("ShapeTool", "Start editing the Shape in the Scene View.");
|
||||
internal static readonly GUIContent shapeToolPro = IconContent("ShapeToolPro", "Start editing the Shape in the Scene View.");
|
||||
|
||||
internal static GUIContent IconContent(string name, string tooltip = null)
|
||||
{
|
||||
return new GUIContent(AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/" + name + ".png"), tooltip);
|
||||
}
|
||||
|
||||
public static GUIContent icon
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
return shapeToolPro;
|
||||
|
||||
return shapeToolIcon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal interface IDuringSceneGuiTool
|
||||
{
|
||||
void DuringSceneGui(SceneView sceneView);
|
||||
bool IsAvailable();
|
||||
}
|
||||
|
||||
[InitializeOnLoad]
|
||||
internal class EditorToolManager
|
||||
{
|
||||
private static List<IDuringSceneGuiTool> m_Tools = new List<IDuringSceneGuiTool>();
|
||||
|
||||
static EditorToolManager()
|
||||
{
|
||||
SceneView.duringSceneGui += DuringSceneGui;
|
||||
}
|
||||
|
||||
internal static void Add(IDuringSceneGuiTool tool)
|
||||
{
|
||||
if (!m_Tools.Contains(tool) && tool is EditorTool)
|
||||
m_Tools.Add(tool);
|
||||
}
|
||||
|
||||
internal static void Remove(IDuringSceneGuiTool tool)
|
||||
{
|
||||
if (m_Tools.Contains(tool))
|
||||
m_Tools.Remove(tool);
|
||||
}
|
||||
|
||||
internal static bool IsActiveTool<T>() where T : EditorTool
|
||||
{
|
||||
return EditorTools.EditorTools.activeToolType.Equals(typeof(T));
|
||||
}
|
||||
|
||||
internal static bool IsAvailable<T>() where T : EditorTool
|
||||
{
|
||||
var tool = GetEditorTool<T>();
|
||||
|
||||
if (tool != null)
|
||||
return tool.IsAvailable();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static T GetEditorTool<T>() where T : EditorTool
|
||||
{
|
||||
foreach(var tool in m_Tools)
|
||||
{
|
||||
if (tool.GetType().Equals(typeof(T)))
|
||||
return tool as T;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void DuringSceneGui(SceneView sceneView)
|
||||
{
|
||||
foreach (var tool in m_Tools)
|
||||
{
|
||||
if (tool.IsAvailable() && EditorTools.EditorTools.IsActiveTool(tool as EditorTool))
|
||||
tool.DuringSceneGui(sceneView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class PathEditorTool<T> : EditorTool, IDuringSceneGuiTool where T : ScriptablePath
|
||||
{
|
||||
private Dictionary<UnityObject, T> m_Paths = new Dictionary<UnityObject, T>();
|
||||
private IGUIState m_GUIState = new GUIState();
|
||||
private Dictionary<UnityObject, PathEditor> m_PathEditors = new Dictionary<UnityObject, PathEditor>();
|
||||
private Dictionary<UnityObject, SerializedObject> m_SerializedObjects = new Dictionary<UnityObject, SerializedObject>();
|
||||
private MultipleEditablePathController m_Controller = new MultipleEditablePathController();
|
||||
private PointRectSelector m_RectSelector = new PointRectSelector();
|
||||
private bool m_IsActive = false;
|
||||
|
||||
internal T[] paths
|
||||
{
|
||||
get { return m_Paths.Values.ToArray(); }
|
||||
}
|
||||
|
||||
public bool enableSnapping
|
||||
{
|
||||
get { return m_Controller.enableSnapping; }
|
||||
set { m_Controller.enableSnapping = value; }
|
||||
}
|
||||
|
||||
public override GUIContent toolbarIcon
|
||||
{
|
||||
get { return PathEditorToolContents.icon; }
|
||||
}
|
||||
|
||||
public override bool IsAvailable()
|
||||
{
|
||||
return targets.Count() > 0;
|
||||
}
|
||||
|
||||
public T GetPath(UnityObject targetObject)
|
||||
{
|
||||
var path = default(T);
|
||||
m_Paths.TryGetValue(targetObject, out path);
|
||||
return path;
|
||||
}
|
||||
|
||||
public void SetPath(UnityObject target)
|
||||
{
|
||||
var path = GetPath(target);
|
||||
path.localToWorldMatrix = Matrix4x4.identity;
|
||||
|
||||
var undoName = Undo.GetCurrentGroupName();
|
||||
var serializedObject = GetSerializedObject(target);
|
||||
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
|
||||
SetShape(path, serializedObject);
|
||||
|
||||
Undo.SetCurrentGroupName(undoName);
|
||||
}
|
||||
|
||||
private void RepaintInspectors()
|
||||
{
|
||||
var editorWindows = Resources.FindObjectsOfTypeAll<EditorWindow>();
|
||||
|
||||
foreach (var editorWindow in editorWindows)
|
||||
{
|
||||
if (editorWindow.titleContent.text == "Inspector")
|
||||
editorWindow.Repaint();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_IsActive = false;
|
||||
EditorToolManager.Add(this);
|
||||
|
||||
SetupRectSelector();
|
||||
HandleActivation();
|
||||
|
||||
EditorTools.EditorTools.activeToolChanged += HandleActivation;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
EditorToolManager.Remove(this);
|
||||
|
||||
EditorTools.EditorTools.activeToolChanged -= HandleActivation;
|
||||
UnregisterCallbacks();
|
||||
}
|
||||
|
||||
private void HandleActivation()
|
||||
{
|
||||
if (m_IsActive == false && EditorTools.EditorTools.IsActiveTool(this))
|
||||
Activate();
|
||||
else if (m_IsActive)
|
||||
Deactivate();
|
||||
}
|
||||
|
||||
private void Activate()
|
||||
{
|
||||
m_IsActive = true;
|
||||
RegisterCallbacks();
|
||||
InitializeCache();
|
||||
OnActivate();
|
||||
}
|
||||
|
||||
private void Deactivate()
|
||||
{
|
||||
OnDeactivate();
|
||||
DestroyCache();
|
||||
UnregisterCallbacks();
|
||||
m_IsActive = false;
|
||||
}
|
||||
|
||||
private void RegisterCallbacks()
|
||||
{
|
||||
UnregisterCallbacks();
|
||||
Selection.selectionChanged += SelectionChanged;
|
||||
EditorApplication.playModeStateChanged += PlayModeStateChanged;
|
||||
Undo.undoRedoPerformed += UndoRedoPerformed;
|
||||
}
|
||||
|
||||
private void UnregisterCallbacks()
|
||||
{
|
||||
Selection.selectionChanged -= SelectionChanged;
|
||||
EditorApplication.playModeStateChanged -= PlayModeStateChanged;
|
||||
Undo.undoRedoPerformed -= UndoRedoPerformed;
|
||||
}
|
||||
|
||||
private void DestroyCache()
|
||||
{
|
||||
foreach (var pair in m_Paths)
|
||||
{
|
||||
var path = pair.Value;
|
||||
|
||||
if (path != null)
|
||||
{
|
||||
Undo.ClearUndo(path);
|
||||
UnityObject.DestroyImmediate(path);
|
||||
}
|
||||
}
|
||||
m_Paths.Clear();
|
||||
m_Controller.ClearPaths();
|
||||
m_PathEditors.Clear();
|
||||
m_SerializedObjects.Clear();
|
||||
}
|
||||
|
||||
private void UndoRedoPerformed()
|
||||
{
|
||||
ForEachTarget((target) =>
|
||||
{
|
||||
var path = GetPath(target);
|
||||
|
||||
if (!path.modified)
|
||||
InitializePath(target);
|
||||
});
|
||||
}
|
||||
|
||||
private void SelectionChanged()
|
||||
{
|
||||
InitializeCache();
|
||||
}
|
||||
|
||||
private void PlayModeStateChanged(PlayModeStateChange stateChange)
|
||||
{
|
||||
if (stateChange == PlayModeStateChange.EnteredEditMode)
|
||||
EditorApplication.delayCall += () => { InitializeCache(); }; //HACK: At this point target is null. Let's wait to next frame to refresh.
|
||||
}
|
||||
|
||||
private void SetupRectSelector()
|
||||
{
|
||||
m_RectSelector.onSelectionBegin = BeginSelection;
|
||||
m_RectSelector.onSelectionChanged = UpdateSelection;
|
||||
m_RectSelector.onSelectionEnd = EndSelection;
|
||||
}
|
||||
|
||||
private void ForEachTarget(Action<UnityObject> action)
|
||||
{
|
||||
foreach(var target in targets)
|
||||
{
|
||||
if (target == null)
|
||||
continue;
|
||||
|
||||
action(target);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeCache()
|
||||
{
|
||||
m_Controller.ClearPaths();
|
||||
|
||||
ForEachTarget((target) =>
|
||||
{
|
||||
var path = GetOrCreatePath(target);
|
||||
var pointCount = path.pointCount;
|
||||
|
||||
InitializePath(target);
|
||||
|
||||
if (pointCount != path.pointCount)
|
||||
path.selection.Clear();
|
||||
|
||||
CreatePathEditor(target);
|
||||
|
||||
m_Controller.AddPath(path);
|
||||
});
|
||||
}
|
||||
|
||||
private void InitializePath(UnityObject target)
|
||||
{
|
||||
IShape shape = null;
|
||||
ControlPoint[] controlPoints = null;
|
||||
|
||||
try
|
||||
{
|
||||
shape = GetShape(target);
|
||||
controlPoints = shape.ToControlPoints();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e.Message);
|
||||
}
|
||||
|
||||
var path = GetPath(target);
|
||||
path.Clear();
|
||||
|
||||
if (shape != null && controlPoints != null)
|
||||
{
|
||||
path.localToWorldMatrix = Matrix4x4.identity;
|
||||
path.shapeType = shape.type;
|
||||
path.isOpenEnded = shape.isOpenEnded;
|
||||
|
||||
foreach (var controlPoint in controlPoints)
|
||||
path.AddPoint(controlPoint);
|
||||
}
|
||||
|
||||
Initialize(path, GetSerializedObject(target));
|
||||
}
|
||||
|
||||
private T GetOrCreatePath(UnityObject targetObject)
|
||||
{
|
||||
var path = GetPath(targetObject);
|
||||
|
||||
if (path == null)
|
||||
{
|
||||
path = ScriptableObject.CreateInstance<T>();
|
||||
path.owner = targetObject;
|
||||
m_Paths[targetObject] = path;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private PathEditor GetPathEditor(UnityObject target)
|
||||
{
|
||||
PathEditor pathEditor;
|
||||
m_PathEditors.TryGetValue(target, out pathEditor);
|
||||
return pathEditor;
|
||||
}
|
||||
|
||||
private void CreatePathEditor(UnityObject target)
|
||||
{
|
||||
var pathEditor = new PathEditor();
|
||||
pathEditor.controller = m_Controller;
|
||||
pathEditor.drawerOverride = GetCustomDrawer(target);
|
||||
m_PathEditors[target] = pathEditor;
|
||||
}
|
||||
|
||||
private SerializedObject GetSerializedObject(UnityObject target)
|
||||
{
|
||||
var serializedObject = default(SerializedObject);
|
||||
|
||||
if (!m_SerializedObjects.TryGetValue(target, out serializedObject))
|
||||
{
|
||||
serializedObject = new SerializedObject(target);
|
||||
m_SerializedObjects[target] = serializedObject;
|
||||
}
|
||||
|
||||
return serializedObject;
|
||||
}
|
||||
|
||||
void IDuringSceneGuiTool.DuringSceneGui(SceneView sceneView)
|
||||
{
|
||||
if (m_GUIState.eventType == EventType.Layout)
|
||||
m_Controller.ClearClosestPath();
|
||||
|
||||
m_RectSelector.OnGUI();
|
||||
|
||||
bool changed = false;
|
||||
|
||||
ForEachTarget((target) =>
|
||||
{
|
||||
var path = GetPath(target);
|
||||
|
||||
if (path != null)
|
||||
{
|
||||
path.localToWorldMatrix = GetLocalToWorldMatrix(target);
|
||||
path.forward = GetForward(target);
|
||||
path.up = GetUp(target);
|
||||
path.right = GetRight(target);
|
||||
m_Controller.editablePath = path;
|
||||
|
||||
using (var check = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
var pathEditor = GetPathEditor(target);
|
||||
pathEditor.linearTangentIsZero = GetLinearTangentIsZero(target);
|
||||
pathEditor.OnGUI();
|
||||
OnCustomGUI(path);
|
||||
changed |= check.changed;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (changed)
|
||||
{
|
||||
SetShapes();
|
||||
RepaintInspectors();
|
||||
}
|
||||
}
|
||||
|
||||
private void BeginSelection(ISelector<Vector3> selector, bool isAdditive)
|
||||
{
|
||||
m_Controller.RegisterUndo("Selection");
|
||||
|
||||
if (isAdditive)
|
||||
{
|
||||
ForEachTarget((target) =>
|
||||
{
|
||||
var path = GetPath(target);
|
||||
path.selection.BeginSelection();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateSelection(selector);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSelection(ISelector<Vector3> selector)
|
||||
{
|
||||
var repaintInspectors = false;
|
||||
|
||||
ForEachTarget((target) =>
|
||||
{
|
||||
var path = GetPath(target);
|
||||
|
||||
repaintInspectors |= path.Select(selector);
|
||||
});
|
||||
|
||||
if (repaintInspectors)
|
||||
RepaintInspectors();
|
||||
}
|
||||
|
||||
private void EndSelection(ISelector<Vector3> selector)
|
||||
{
|
||||
ForEachTarget((target) =>
|
||||
{
|
||||
var path = GetPath(target);
|
||||
path.selection.EndSelection(true);
|
||||
});
|
||||
}
|
||||
|
||||
internal void SetShapes()
|
||||
{
|
||||
ForEachTarget((target) =>
|
||||
{
|
||||
SetPath(target);
|
||||
});
|
||||
}
|
||||
|
||||
private Transform GetTransform(UnityObject target)
|
||||
{
|
||||
return (target as Component).transform;
|
||||
}
|
||||
|
||||
private Matrix4x4 GetLocalToWorldMatrix(UnityObject target)
|
||||
{
|
||||
return GetTransform(target).localToWorldMatrix;
|
||||
}
|
||||
|
||||
private Vector3 GetForward(UnityObject target)
|
||||
{
|
||||
return GetTransform(target).forward;
|
||||
}
|
||||
|
||||
private Vector3 GetUp(UnityObject target)
|
||||
{
|
||||
return GetTransform(target).up;
|
||||
}
|
||||
|
||||
private Vector3 GetRight(UnityObject target)
|
||||
{
|
||||
return GetTransform(target).right;
|
||||
}
|
||||
|
||||
protected abstract IShape GetShape(UnityObject target);
|
||||
protected virtual void Initialize(T path, SerializedObject serializedObject) { }
|
||||
protected abstract void SetShape(T path, SerializedObject serializedObject);
|
||||
protected virtual void OnActivate() { }
|
||||
protected virtual void OnDeactivate() { }
|
||||
protected virtual void OnCustomGUI(T path) { }
|
||||
protected virtual bool GetLinearTangentIsZero(UnityObject target) { return false; }
|
||||
protected virtual IDrawer GetCustomDrawer(UnityObject target) { return null; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 320732be5a65ff84ea451c5bf9700876
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,108 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.EditorTools;
|
||||
using UnityEditor.U2D.Path.GUIFramework;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public static class PathEditorToolExtensions
|
||||
{
|
||||
public static void CycleTangentMode<T>(this PathEditorTool<T> pathEditorTool) where T : ScriptablePath
|
||||
{
|
||||
var first = true;
|
||||
var mixed = false;
|
||||
var tangentMode = TangentMode.Linear;
|
||||
var targets = pathEditorTool.targets;
|
||||
|
||||
foreach(var target in targets)
|
||||
{
|
||||
var path = pathEditorTool.GetPath(target);
|
||||
|
||||
if (path.selection.Count == 0)
|
||||
continue;
|
||||
|
||||
for (var i = 0; i < path.pointCount; ++i)
|
||||
{
|
||||
if (!path.selection.Contains(i))
|
||||
continue;
|
||||
|
||||
var point = path.GetPoint(i);
|
||||
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
tangentMode = point.tangentMode;
|
||||
}
|
||||
else if (point.tangentMode != tangentMode)
|
||||
{
|
||||
mixed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mixed)
|
||||
break;
|
||||
}
|
||||
|
||||
if (mixed)
|
||||
tangentMode = TangentMode.Linear;
|
||||
else
|
||||
tangentMode = GetNextTangentMode(tangentMode);
|
||||
|
||||
foreach(var target in targets)
|
||||
{
|
||||
var path = pathEditorTool.GetPath(target);
|
||||
|
||||
if (path.selection.Count == 0)
|
||||
continue;
|
||||
|
||||
path.undoObject.RegisterUndo("Cycle Tangent Mode");
|
||||
|
||||
for (var i = 0; i < path.pointCount; ++i)
|
||||
{
|
||||
if (!path.selection.Contains(i))
|
||||
continue;
|
||||
|
||||
path.SetTangentMode(i, tangentMode);
|
||||
}
|
||||
|
||||
pathEditorTool.SetPath(target);
|
||||
}
|
||||
}
|
||||
|
||||
public static void MirrorTangent<T>(this PathEditorTool<T> pathEditorTool) where T : ScriptablePath
|
||||
{
|
||||
var targets = pathEditorTool.targets;
|
||||
|
||||
foreach(var target in targets)
|
||||
{
|
||||
var path = pathEditorTool.GetPath(target);
|
||||
|
||||
if (path.selection.Count == 0)
|
||||
continue;
|
||||
|
||||
path.undoObject.RegisterUndo("Mirror Tangents");
|
||||
|
||||
for (var i = 0; i < path.pointCount; ++i)
|
||||
{
|
||||
if (!path.selection.Contains(i))
|
||||
continue;
|
||||
|
||||
path.MirrorTangent(i);
|
||||
}
|
||||
|
||||
pathEditorTool.SetPath(target);
|
||||
}
|
||||
}
|
||||
|
||||
private static TangentMode GetNextTangentMode(TangentMode tangentMode)
|
||||
{
|
||||
return (TangentMode)((((int)tangentMode) + 1) % Enum.GetValues(typeof(TangentMode)).Length);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 94a1e3e609709aa4f9106a9aeea179f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public class ScriptableData<T> : ScriptableObject
|
||||
{
|
||||
[SerializeField]
|
||||
private T m_Data;
|
||||
public UnityObject owner { get; set; }
|
||||
public int index { get; set; }
|
||||
|
||||
public T data
|
||||
{
|
||||
get { return m_Data; }
|
||||
set { m_Data = value; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ae511f1b2818bc54f87b84a327b16f71
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,118 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.EditorTools;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public class ScriptablePath : ScriptableObject, IEditablePath, IUndoObject
|
||||
{
|
||||
[SerializeField]
|
||||
private EditablePath m_EditablePath = new EditablePath();
|
||||
[SerializeField]
|
||||
private bool m_Modified = false;
|
||||
|
||||
internal bool modified
|
||||
{
|
||||
get { return m_Modified; }
|
||||
}
|
||||
|
||||
internal UnityObject owner { get; set; }
|
||||
|
||||
public ShapeType shapeType
|
||||
{
|
||||
get { return m_EditablePath.shapeType; }
|
||||
set { m_EditablePath.shapeType = value; }
|
||||
}
|
||||
|
||||
public IUndoObject undoObject
|
||||
{
|
||||
get { return this; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public ISelection<int> selection
|
||||
{
|
||||
get { return m_EditablePath.selection; }
|
||||
}
|
||||
|
||||
public Matrix4x4 localToWorldMatrix
|
||||
{
|
||||
get { return m_EditablePath.localToWorldMatrix; }
|
||||
set { m_EditablePath.localToWorldMatrix = value; }
|
||||
}
|
||||
|
||||
public Vector3 forward
|
||||
{
|
||||
get { return m_EditablePath.forward; }
|
||||
set { m_EditablePath.forward = value; }
|
||||
}
|
||||
|
||||
public Vector3 up
|
||||
{
|
||||
get { return m_EditablePath.up; }
|
||||
set { m_EditablePath.up = value; }
|
||||
}
|
||||
|
||||
public Vector3 right
|
||||
{
|
||||
get { return m_EditablePath.right; }
|
||||
set { m_EditablePath.right = value; }
|
||||
}
|
||||
|
||||
public bool isOpenEnded
|
||||
{
|
||||
get { return m_EditablePath.isOpenEnded; }
|
||||
set { m_EditablePath.isOpenEnded = value; }
|
||||
}
|
||||
|
||||
public int pointCount
|
||||
{
|
||||
get { return m_EditablePath.pointCount; }
|
||||
}
|
||||
|
||||
public bool Select(ISelector<Vector3> selector)
|
||||
{
|
||||
return m_EditablePath.Select(selector);
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
m_EditablePath.Clear();
|
||||
}
|
||||
|
||||
public virtual ControlPoint GetPoint(int index)
|
||||
{
|
||||
return m_EditablePath.GetPoint(index);
|
||||
}
|
||||
|
||||
public virtual void SetPoint(int index, ControlPoint controlPoint)
|
||||
{
|
||||
m_EditablePath.SetPoint(index, controlPoint);
|
||||
}
|
||||
|
||||
public virtual void AddPoint(ControlPoint controlPoint)
|
||||
{
|
||||
m_EditablePath.AddPoint(controlPoint);
|
||||
}
|
||||
|
||||
public virtual void InsertPoint(int index, ControlPoint controlPoint)
|
||||
{
|
||||
m_EditablePath.InsertPoint(index, controlPoint);
|
||||
}
|
||||
|
||||
public virtual void RemovePoint(int index)
|
||||
{
|
||||
m_EditablePath.RemovePoint(index);
|
||||
}
|
||||
|
||||
void IUndoObject.RegisterUndo(string name)
|
||||
{
|
||||
Undo.RegisterCompleteObjectUndo(this, name);
|
||||
m_Modified = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c208d96210d896247a45095d5fa9bf09
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,233 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
[CanEditMultipleObjects]
|
||||
[CustomEditor(typeof(ScriptablePath), true)]
|
||||
public class ScriptablePathInspector : Editor
|
||||
{
|
||||
private static class Contents
|
||||
{
|
||||
public static readonly GUIContent linearIcon = IconContent("TangentLinear", "TangentLinearPro", "Linear");
|
||||
public static readonly GUIContent continuousIcon = IconContent("TangentContinuous", "TangentContinuousPro", "Continuous");
|
||||
public static readonly GUIContent brokenIcon = IconContent("TangentBroken", "TangentBrokenPro", "Broken");
|
||||
public static readonly GUIContent positionLabel = new GUIContent("Position", "Position of the Control Point");
|
||||
public static readonly GUIContent enableSnapLabel = new GUIContent("Snapping", "Snap points using the snap settings");
|
||||
public static readonly GUIContent tangentModeLabel = new GUIContent("Tangent Mode");
|
||||
public static readonly GUIContent pointLabel = new GUIContent("Point");
|
||||
|
||||
|
||||
private static GUIContent IconContent(string name, string tooltip = null)
|
||||
{
|
||||
return new GUIContent(AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/" + name + ".png"), tooltip);
|
||||
}
|
||||
|
||||
private static GUIContent IconContent(string personal, string pro, string tooltip)
|
||||
{
|
||||
if (EditorGUIUtility.isProSkin)
|
||||
return IconContent(pro, tooltip);
|
||||
|
||||
return IconContent(personal, tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ScriptablePath> m_Paths = null;
|
||||
private bool m_Dragged = false;
|
||||
|
||||
protected List<ScriptablePath> paths
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Paths == null)
|
||||
m_Paths = targets.Select( t => t as ScriptablePath).ToList();
|
||||
|
||||
return m_Paths;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
DoTangentModeInspector();
|
||||
DoPositionInspector();
|
||||
}
|
||||
|
||||
protected void DoTangentModeInspector()
|
||||
{
|
||||
if (!IsAnyShapeType(ShapeType.Spline))
|
||||
return;
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel(Contents.tangentModeLabel);
|
||||
|
||||
using (new EditorGUI.DisabledGroupScope(!IsAnyPointSelected()))
|
||||
{
|
||||
if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Linear), Contents.linearIcon))
|
||||
SetMixedTangentMode(TangentMode.Linear);
|
||||
|
||||
if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Continuous), Contents.continuousIcon))
|
||||
SetMixedTangentMode(TangentMode.Continuous);
|
||||
|
||||
if (DoToggle(GetToggleStateFromTangentMode(TangentMode.Broken), Contents.brokenIcon))
|
||||
SetMixedTangentMode(TangentMode.Broken);
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
protected void DoPositionInspector()
|
||||
{
|
||||
var showMixedValue = EditorGUI.showMixedValue;
|
||||
var wideMode = EditorGUIUtility.wideMode;
|
||||
|
||||
var position = Vector3.zero;
|
||||
var isMixed = GetMixedPosition(out position);
|
||||
|
||||
EditorGUI.showMixedValue = isMixed;
|
||||
EditorGUIUtility.wideMode = true;
|
||||
|
||||
using (new EditorGUI.DisabledGroupScope(!IsAnyPointSelected()))
|
||||
{
|
||||
if (GUIUtility.hotControl == 0)
|
||||
m_Dragged = false;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
var delta = EditorGUILayout.Vector2Field(Contents.positionLabel, position) - (Vector2)position;
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
if (m_Dragged == false)
|
||||
{
|
||||
foreach(var path in paths)
|
||||
path.undoObject.RegisterUndo("Point Position");
|
||||
|
||||
m_Dragged = true;
|
||||
}
|
||||
|
||||
SetMixedDeltaPosition(delta);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.showMixedValue = showMixedValue;
|
||||
EditorGUIUtility.wideMode = wideMode;
|
||||
}
|
||||
|
||||
private bool DoToggle(bool value, GUIContent icon)
|
||||
{
|
||||
const float kButtonWidth = 33f;
|
||||
const float kButtonHeight = 23f;
|
||||
var buttonStyle = new GUIStyle("EditModeSingleButton");
|
||||
|
||||
var changed = false;
|
||||
using (var check = new EditorGUI.ChangeCheckScope())
|
||||
{
|
||||
value = GUILayout.Toggle(value, icon, buttonStyle, GUILayout.Width(kButtonWidth), GUILayout.Height(kButtonHeight));
|
||||
changed = check.changed;
|
||||
}
|
||||
|
||||
return value && changed;
|
||||
}
|
||||
|
||||
private bool GetToggleStateFromTangentMode(TangentMode mode)
|
||||
{
|
||||
foreach(var path in paths)
|
||||
{
|
||||
var selection = path.selection;
|
||||
|
||||
foreach (var index in selection.elements)
|
||||
if (path.GetPoint(index).tangentMode != mode)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetMixedTangentMode(TangentMode tangentMode)
|
||||
{
|
||||
foreach(var path in paths)
|
||||
{
|
||||
path.undoObject.RegisterUndo("Tangent Mode");
|
||||
|
||||
foreach (var index in path.selection.elements)
|
||||
path.SetTangentMode(index, tangentMode);
|
||||
}
|
||||
|
||||
SceneView.RepaintAll();
|
||||
}
|
||||
|
||||
private bool GetMixedPosition(out Vector3 position)
|
||||
{
|
||||
var first = true;
|
||||
position = Vector3.zero;
|
||||
|
||||
foreach(var path in paths)
|
||||
{
|
||||
var selection = path.selection;
|
||||
var matrix = path.localToWorldMatrix;
|
||||
|
||||
path.localToWorldMatrix = Matrix4x4.identity;
|
||||
|
||||
foreach (var index in selection.elements)
|
||||
{
|
||||
var controlPoint = path.GetPoint(index);
|
||||
|
||||
if (first)
|
||||
{
|
||||
position = controlPoint.position;
|
||||
first = false;
|
||||
}
|
||||
else if (position != controlPoint.position)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
path.localToWorldMatrix = matrix;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SetMixedDeltaPosition(Vector3 delta)
|
||||
{
|
||||
foreach(var path in paths)
|
||||
{
|
||||
var selection = path.selection;
|
||||
var matrix = path.localToWorldMatrix;
|
||||
|
||||
path.localToWorldMatrix = Matrix4x4.identity;
|
||||
|
||||
foreach (var index in selection.elements)
|
||||
{
|
||||
var controlPoint = path.GetPoint(index);
|
||||
controlPoint.position += delta;
|
||||
path.SetPoint(index, controlPoint);
|
||||
}
|
||||
|
||||
path.localToWorldMatrix = matrix;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsAnyShapeType(ShapeType shapeType)
|
||||
{
|
||||
foreach(var path in paths)
|
||||
if (path.shapeType == shapeType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected bool IsAnyPointSelected()
|
||||
{
|
||||
foreach(var path in paths)
|
||||
if (path.selection.Count > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6c5abda88d831f347a177bb63ff287b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ef3a2c79978afd74ebaa435c12615c7c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cbe8f28ead47977409438cd59447d211
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 390 B |
|
@ -0,0 +1,112 @@
|
|||
fileFormatVersion: 2
|
||||
guid: eaa90b7bb801a1144b58c4926d95ad6a
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 357346b6d26030047a52ccb34ccb2886
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 444 B |
|
@ -0,0 +1,112 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 514bcbaba91a4704599b5b170200682a
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 36cdba5fd2caa914892902a32774cdb8
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 507 B |
|
@ -0,0 +1,112 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1d3a30b709ec7b94ab8997b21eae5849
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 52d8d99422b17e64bb6ba5d2dadd70b8
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 474 B |
|
@ -0,0 +1,112 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9becc394fda44db46ad1fbff4a9cfdcb
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 91172ab64c40f144eb1defedd68e7218
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 403 B |
|
@ -0,0 +1,123 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0ece669b27aea44439cadb539418c627
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: tvOS
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: eff7069ffebc20e47b1b8409488587d1
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 326 B |
|
@ -0,0 +1,91 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0601759dc49769849996e4dae10a2204
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 7d56a60e2671206419ca3f0fd4afcc25
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 363 B |
|
@ -0,0 +1,91 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 20ac412813dce2241a95fcf2dad05436
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 3ec3e0affb347e74d962381e838269f3
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 373 B |
|
@ -0,0 +1,91 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b370d25fdf6f8914287e27c0c3dede6a
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 11161a62eb582114f995922f83b5d391
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 366 B |
|
@ -0,0 +1,91 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3f0215e89d05b544d907d3a7d34fab63
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: cbd45795318e3a543936d9b2e6e50606
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 322 B |
|
@ -0,0 +1,91 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 229e750703f3e824ca71ddd16a5e36be
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 89b1ca0030b965c4f82777d37f1e12bc
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 325 B |
|
@ -0,0 +1,91 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8d4a2ded892e27742bb6d4d263639dff
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 65e01b4dd520e304083281f74ebff12e
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 351 B |
|
@ -0,0 +1,91 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a728d9332cba5f448a36350199dc573b
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 62f46dae558c8a74da5ce1603e2ef2a8
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 381 B |
|
@ -0,0 +1,91 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cafc16189f045f445bad6f5eb9e13541
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
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
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 1
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 8426c25057e87a249bbaaea6173778ab
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 66ae7362289f12c4d8da3f9f04cf4984
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEditor.U2D.Path.GUIFramework;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public class CreatePointAction : ClickAction
|
||||
{
|
||||
private Control m_PointControl;
|
||||
|
||||
public Func<IGUIState, Vector2, Vector3> guiToWorld;
|
||||
public Action<int, Vector3> onCreatePoint;
|
||||
public CreatePointAction(Control pointControl, Control edgeControl) : base(edgeControl, 0, false)
|
||||
{
|
||||
m_PointControl = pointControl;
|
||||
}
|
||||
|
||||
protected override void OnTrigger(IGUIState guiState)
|
||||
{
|
||||
base.OnTrigger(guiState);
|
||||
|
||||
var index = hoveredControl.layoutData.index;
|
||||
var position = GetMousePositionWorld(guiState);
|
||||
|
||||
if (onCreatePoint != null)
|
||||
onCreatePoint(index, position);
|
||||
|
||||
guiState.nearestControl = m_PointControl.ID;
|
||||
|
||||
var data = m_PointControl.layoutData;
|
||||
data.index = index + 1;
|
||||
data.position = position;
|
||||
data.distance = 0f;
|
||||
|
||||
m_PointControl.layoutData = data;
|
||||
|
||||
guiState.changed = true;
|
||||
}
|
||||
|
||||
private Vector3 GetMousePositionWorld(IGUIState guiState)
|
||||
{
|
||||
if (guiToWorld != null)
|
||||
return guiToWorld(guiState, guiState.mousePosition);
|
||||
|
||||
return guiState.GUIToWorld(guiState.mousePosition, hoveredControl.layoutData.forward, hoveredControl.layoutData.position);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ed2cb354a5d670f4881c41d7d2fc6a45
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,118 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.U2D.Path.GUIFramework;
|
||||
|
||||
namespace UnityEditor.U2D.Path
|
||||
{
|
||||
public class Drawer : IDrawer
|
||||
{
|
||||
internal class Styles
|
||||
{
|
||||
public readonly GUIStyle pointNormalStyle;
|
||||
public readonly GUIStyle pointHoveredStyle;
|
||||
public readonly GUIStyle pointSelectedStyle;
|
||||
public readonly GUIStyle pointPreviewStyle;
|
||||
public readonly GUIStyle tangentNormalStyle;
|
||||
public readonly GUIStyle tangentHoveredStyle;
|
||||
|
||||
public Styles()
|
||||
{
|
||||
var pointNormal = AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/Path/pointNormal.png");
|
||||
var pointHovered = AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/Path/pointHovered.png");
|
||||
var pointSelected = AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/Path/pointSelected.png");
|
||||
var pointPreview = AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/Path/pointPreview.png");
|
||||
var tangentNormal = AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/Path/tangentNormal.png");
|
||||
|
||||
pointNormalStyle = CreateStyle(AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/Path/pointNormal.png"), Vector2.one * 12f);
|
||||
pointHoveredStyle = CreateStyle(AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/Path/pointHovered.png"), Vector2.one * 12f);
|
||||
pointSelectedStyle = CreateStyle(AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/Path/pointSelected.png"), Vector2.one * 12f);
|
||||
pointPreviewStyle = CreateStyle(AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/Path/pointPreview.png"), Vector2.one * 12f);
|
||||
tangentNormalStyle = CreateStyle(AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/Path/tangentNormal.png"), Vector2.one * 8f);
|
||||
tangentHoveredStyle = CreateStyle(AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.2d.path/Editor/Handles/Path/pointHovered.png"), Vector2.one * 10f);
|
||||
}
|
||||
|
||||
private GUIStyle CreateStyle(Texture2D texture, Vector2 size)
|
||||
{
|
||||
var guiStyle = new GUIStyle();
|
||||
guiStyle.normal.background = texture;
|
||||
guiStyle.fixedWidth = size.x;
|
||||
guiStyle.fixedHeight = size.y;
|
||||
|
||||
return guiStyle;
|
||||
}
|
||||
}
|
||||
|
||||
private IGUIState m_GUIState = new GUIState();
|
||||
private Styles m_Styles;
|
||||
private Styles styles
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Styles == null)
|
||||
m_Styles = new Styles();
|
||||
|
||||
return m_Styles;
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawCreatePointPreview(Vector3 position)
|
||||
{
|
||||
DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointPreviewStyle);
|
||||
}
|
||||
|
||||
public void DrawPoint(Vector3 position)
|
||||
{
|
||||
DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointNormalStyle);
|
||||
}
|
||||
|
||||
public void DrawPointHovered(Vector3 position)
|
||||
{
|
||||
DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointHoveredStyle);
|
||||
}
|
||||
|
||||
public void DrawPointSelected(Vector3 position)
|
||||
{
|
||||
DrawGUIStyleCap(0, position, Quaternion.identity, m_GUIState.GetHandleSize(position), styles.pointSelectedStyle);
|
||||
}
|
||||
|
||||
public void DrawLine(Vector3 p1, Vector3 p2, float width, Color color)
|
||||
{
|
||||
Handles.color = color;
|
||||
Handles.DrawAAPolyLine(width, new Vector3[] { p1, p2 });
|
||||
}
|
||||
|
||||
public void DrawBezier(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, float width, Color color)
|
||||
{
|
||||
Handles.color = color;
|
||||
Handles.DrawBezier(p1, p4, p2, p3, color, null, width);
|
||||
}
|
||||
|
||||
public void DrawTangent(Vector3 position, Vector3 tangent)
|
||||
{
|
||||
DrawLine(position, tangent, 3f, Color.yellow);
|
||||
DrawGUIStyleCap(0, tangent, Quaternion.identity, m_GUIState.GetHandleSize(tangent), styles.tangentNormalStyle);
|
||||
}
|
||||
|
||||
|
||||
private void DrawGUIStyleCap(int controlID, Vector3 position, Quaternion rotation, float size, GUIStyle guiStyle)
|
||||
{
|
||||
if (Camera.current && Vector3.Dot(position - Camera.current.transform.position, Camera.current.transform.forward) < 0f)
|
||||
return;
|
||||
|
||||
Handles.BeginGUI();
|
||||
guiStyle.Draw(GetGUIStyleRect(guiStyle, position), GUIContent.none, controlID);
|
||||
Handles.EndGUI();
|
||||
}
|
||||
|
||||
private Rect GetGUIStyleRect(GUIStyle style, Vector3 position)
|
||||
{
|
||||
Vector2 vector = HandleUtility.WorldToGUIPoint(position);
|
||||
|
||||
float fixedWidth = style.fixedWidth;
|
||||
float fixedHeight = style.fixedHeight;
|
||||
|
||||
return new Rect(vector.x - fixedWidth / 2f, vector.y - fixedHeight / 2f, fixedWidth, fixedHeight);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1b31573f9ab124c47b5e877a88088db1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 33e44f9d4edce8344a708573c37ebe4a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path.GUIFramework
|
||||
{
|
||||
public class ClickAction : HoveredControlAction
|
||||
{
|
||||
private int m_Button;
|
||||
private bool m_UseEvent;
|
||||
public int clickCount = 1;
|
||||
public Action<IGUIState, Control> onClick;
|
||||
private int m_ClickCounter = 0;
|
||||
|
||||
public ClickAction(Control control, int button, bool useEvent = true) : base(control)
|
||||
{
|
||||
m_Button = button;
|
||||
m_UseEvent = useEvent;
|
||||
}
|
||||
|
||||
protected override bool GetTriggerContidtion(IGUIState guiState)
|
||||
{
|
||||
if (guiState.mouseButton == m_Button && guiState.eventType == EventType.MouseDown)
|
||||
{
|
||||
if (guiState.clickCount == 1)
|
||||
m_ClickCounter = 0;
|
||||
|
||||
++m_ClickCounter;
|
||||
|
||||
if (m_ClickCounter == clickCount)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void OnTrigger(IGUIState guiState)
|
||||
{
|
||||
base.OnTrigger(guiState);
|
||||
|
||||
if (onClick != null)
|
||||
onClick(guiState, hoveredControl);
|
||||
|
||||
if (m_UseEvent)
|
||||
guiState.UseEvent();
|
||||
}
|
||||
|
||||
protected override bool GetFinishContidtion(IGUIState guiState)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 175bf12750eca384fa2ece4cd8f67cd4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path.GUIFramework
|
||||
{
|
||||
public class CommandAction : GUIAction
|
||||
{
|
||||
private string m_CommandName;
|
||||
|
||||
public Action<IGUIState> onCommand;
|
||||
|
||||
public CommandAction(string commandName)
|
||||
{
|
||||
m_CommandName = commandName;
|
||||
}
|
||||
|
||||
protected override bool GetTriggerContidtion(IGUIState guiState)
|
||||
{
|
||||
if (guiState.eventType == EventType.ValidateCommand && guiState.commandName == m_CommandName)
|
||||
{
|
||||
guiState.UseEvent();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool GetFinishContidtion(IGUIState guiState)
|
||||
{
|
||||
if (guiState.eventType == EventType.ExecuteCommand && guiState.commandName == m_CommandName)
|
||||
{
|
||||
guiState.UseEvent();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void OnFinish(IGUIState guiState)
|
||||
{
|
||||
if (onCommand != null)
|
||||
onCommand(guiState);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d8d8b17ba93dfad489ee2c2ff2546fb0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,152 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path.GUIFramework
|
||||
{
|
||||
public abstract class Control
|
||||
{
|
||||
private string m_Name;
|
||||
private int m_NameHashCode;
|
||||
private int m_ID;
|
||||
private LayoutData m_LayoutData;
|
||||
private int m_ActionID = -1;
|
||||
private LayoutData m_HotLayoutData;
|
||||
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
}
|
||||
|
||||
public int ID
|
||||
{
|
||||
get { return m_ID; }
|
||||
}
|
||||
|
||||
public int actionID
|
||||
{
|
||||
get { return m_ActionID; }
|
||||
}
|
||||
|
||||
public LayoutData layoutData
|
||||
{
|
||||
get { return m_LayoutData; }
|
||||
set { m_LayoutData = value; }
|
||||
}
|
||||
|
||||
public LayoutData hotLayoutData
|
||||
{
|
||||
get { return m_HotLayoutData; }
|
||||
}
|
||||
|
||||
public Control(string name)
|
||||
{
|
||||
m_Name = name;
|
||||
m_NameHashCode = name.GetHashCode();
|
||||
}
|
||||
|
||||
public void GetControl(IGUIState guiState)
|
||||
{
|
||||
m_ID = guiState.GetControlID(m_NameHashCode, FocusType.Passive);
|
||||
}
|
||||
|
||||
internal void SetActionID(int actionID)
|
||||
{
|
||||
m_ActionID = actionID;
|
||||
m_HotLayoutData = m_LayoutData;
|
||||
}
|
||||
|
||||
public void BeginLayout(IGUIState guiState)
|
||||
{
|
||||
Debug.Assert(guiState.eventType == EventType.Layout);
|
||||
|
||||
m_LayoutData = OnBeginLayout(LayoutData.zero, guiState);
|
||||
}
|
||||
|
||||
public void Layout(IGUIState guiState)
|
||||
{
|
||||
Debug.Assert(guiState.eventType == EventType.Layout);
|
||||
|
||||
for (var i = 0; i < GetCount(); ++i)
|
||||
{
|
||||
if (guiState.hotControl == actionID && hotLayoutData.index == i)
|
||||
continue;
|
||||
|
||||
var layoutData = new LayoutData()
|
||||
{
|
||||
index = i,
|
||||
position = GetPosition(guiState, i),
|
||||
distance = GetDistance(guiState, i),
|
||||
forward = GetForward(guiState, i),
|
||||
up = GetUp(guiState, i),
|
||||
right = GetRight(guiState, i),
|
||||
userData = GetUserData(guiState, i)
|
||||
};
|
||||
|
||||
m_LayoutData = LayoutData.Nearest(m_LayoutData, layoutData);
|
||||
}
|
||||
}
|
||||
|
||||
public void EndLayout(IGUIState guiState)
|
||||
{
|
||||
Debug.Assert(guiState.eventType == EventType.Layout);
|
||||
|
||||
OnEndLayout(guiState);
|
||||
}
|
||||
|
||||
public void Repaint(IGUIState guiState)
|
||||
{
|
||||
for (var i = 0; i < GetCount(); ++i)
|
||||
OnRepaint(guiState, i);
|
||||
}
|
||||
|
||||
protected virtual LayoutData OnBeginLayout(LayoutData data, IGUIState guiState)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
protected virtual void OnEndLayout(IGUIState guiState)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnRepaint(IGUIState guiState, int index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual int GetCount()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetPosition(IGUIState guiState, int index)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetForward(IGUIState guiState, int index)
|
||||
{
|
||||
return Vector3.forward;
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetUp(IGUIState guiState, int index)
|
||||
{
|
||||
return Vector3.up;
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetRight(IGUIState guiState, int index)
|
||||
{
|
||||
return Vector3.right;
|
||||
}
|
||||
|
||||
protected virtual float GetDistance(IGUIState guiState, int index)
|
||||
{
|
||||
return layoutData.distance;
|
||||
}
|
||||
|
||||
protected virtual object GetUserData(IGUIState guiState, int index)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1ab9c1eea0b4cc74bbee507825f10d5a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path.GUIFramework
|
||||
{
|
||||
public abstract class DefaultControl : Control
|
||||
{
|
||||
public static readonly float kPickDistance = 5f;
|
||||
|
||||
public DefaultControl(string name) : base(name)
|
||||
{
|
||||
}
|
||||
|
||||
protected override LayoutData OnBeginLayout(LayoutData data, IGUIState guiState)
|
||||
{
|
||||
data.distance = kPickDistance;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4dc9a9d2bfd656d4cb3ccb675fe0a426
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,112 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path.GUIFramework
|
||||
{
|
||||
public abstract class GUIAction
|
||||
{
|
||||
private int m_ID = -1;
|
||||
|
||||
public Func<IGUIState, GUIAction, bool> enable;
|
||||
public Func<IGUIState, GUIAction, bool> enableRepaint;
|
||||
public Func<IGUIState, GUIAction, bool> repaintOnMouseMove;
|
||||
public Action<IGUIState, GUIAction> onPreRepaint;
|
||||
public Action<IGUIState, GUIAction> onRepaint;
|
||||
|
||||
public int ID
|
||||
{
|
||||
get { return m_ID; }
|
||||
}
|
||||
|
||||
public void OnGUI(IGUIState guiState)
|
||||
{
|
||||
m_ID = guiState.GetControlID(GetType().GetHashCode(), FocusType.Passive);
|
||||
|
||||
if (guiState.hotControl == 0 && IsEnabled(guiState) && CanTrigger(guiState) && GetTriggerContidtion(guiState))
|
||||
{
|
||||
guiState.hotControl = ID;
|
||||
OnTrigger(guiState);
|
||||
}
|
||||
|
||||
if (guiState.hotControl == ID)
|
||||
{
|
||||
if (GetFinishContidtion(guiState))
|
||||
{
|
||||
OnFinish(guiState);
|
||||
guiState.hotControl = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnPerform(guiState);
|
||||
}
|
||||
}
|
||||
|
||||
if (guiState.eventType == EventType.Repaint && IsRepaintEnabled(guiState))
|
||||
Repaint(guiState);
|
||||
}
|
||||
|
||||
public bool IsEnabled(IGUIState guiState)
|
||||
{
|
||||
if (enable != null)
|
||||
return enable(guiState, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsRepaintEnabled(IGUIState guiState)
|
||||
{
|
||||
if (!IsEnabled(guiState))
|
||||
return false;
|
||||
|
||||
if (enableRepaint != null)
|
||||
return enableRepaint(guiState, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void PreRepaint(IGUIState guiState)
|
||||
{
|
||||
Debug.Assert(guiState.eventType == EventType.Repaint);
|
||||
|
||||
if (IsEnabled(guiState) && onPreRepaint != null)
|
||||
onPreRepaint(guiState, this);
|
||||
}
|
||||
|
||||
private void Repaint(IGUIState guiState)
|
||||
{
|
||||
Debug.Assert(guiState.eventType == EventType.Repaint);
|
||||
|
||||
if (onRepaint != null)
|
||||
onRepaint(guiState, this);
|
||||
}
|
||||
|
||||
internal bool IsRepaintOnMouseMoveEnabled(IGUIState guiState)
|
||||
{
|
||||
if (!IsEnabled(guiState) || !IsRepaintEnabled(guiState))
|
||||
return false;
|
||||
|
||||
if (repaintOnMouseMove != null)
|
||||
return repaintOnMouseMove(guiState, this);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract bool GetFinishContidtion(IGUIState guiState);
|
||||
protected abstract bool GetTriggerContidtion(IGUIState guiState);
|
||||
protected virtual bool CanTrigger(IGUIState guiState) { return true; }
|
||||
protected virtual void OnTrigger(IGUIState guiState)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnPerform(IGUIState guiState)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnFinish(IGUIState guiState)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2f11e220b90636b42bf596fb50ccdb6a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,156 @@
|
|||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityEditor.U2D.Path.GUIFramework
|
||||
{
|
||||
public class GUIState : IGUIState
|
||||
{
|
||||
private Handles.CapFunction nullCap = (int c, Vector3 p , Quaternion r, float s, EventType ev) => {};
|
||||
|
||||
public Vector2 mousePosition
|
||||
{
|
||||
get { return Event.current.mousePosition; }
|
||||
}
|
||||
|
||||
public int mouseButton
|
||||
{
|
||||
get { return Event.current.button; }
|
||||
}
|
||||
|
||||
public int clickCount
|
||||
{
|
||||
get { return Event.current.clickCount; }
|
||||
set { Event.current.clickCount = Mathf.Max(0, value); }
|
||||
}
|
||||
|
||||
public bool isShiftDown
|
||||
{
|
||||
get { return Event.current.shift; }
|
||||
}
|
||||
|
||||
public bool isAltDown
|
||||
{
|
||||
get { return Event.current.alt; }
|
||||
}
|
||||
|
||||
public bool isActionKeyDown
|
||||
{
|
||||
get { return EditorGUI.actionKey; }
|
||||
}
|
||||
|
||||
public KeyCode keyCode
|
||||
{
|
||||
get { return Event.current.keyCode; }
|
||||
}
|
||||
|
||||
public EventType eventType
|
||||
{
|
||||
get { return Event.current.type; }
|
||||
}
|
||||
|
||||
public string commandName
|
||||
{
|
||||
get { return Event.current.commandName; }
|
||||
}
|
||||
|
||||
public int nearestControl
|
||||
{
|
||||
get { return HandleUtility.nearestControl; }
|
||||
set { HandleUtility.nearestControl = value; }
|
||||
}
|
||||
|
||||
public int hotControl
|
||||
{
|
||||
get { return GUIUtility.hotControl; }
|
||||
set { GUIUtility.hotControl = value; }
|
||||
}
|
||||
|
||||
public bool changed
|
||||
{
|
||||
get { return GUI.changed; }
|
||||
set { GUI.changed = value; }
|
||||
}
|
||||
|
||||
public int GetControlID(int hint, FocusType focusType)
|
||||
{
|
||||
return GUIUtility.GetControlID(hint, focusType);
|
||||
}
|
||||
|
||||
public void AddControl(int controlID, float distance)
|
||||
{
|
||||
HandleUtility.AddControl(controlID, distance);
|
||||
}
|
||||
|
||||
public bool Slider(int id, SliderData sliderData, out Vector3 newPosition)
|
||||
{
|
||||
if (mouseButton == 0 && eventType == EventType.MouseDown)
|
||||
{
|
||||
hotControl = 0;
|
||||
nearestControl = id;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
newPosition = Handles.Slider2D(id, sliderData.position, sliderData.forward, sliderData.right, sliderData.up, 1f, nullCap, Vector2.zero);
|
||||
return EditorGUI.EndChangeCheck();
|
||||
}
|
||||
|
||||
public void UseEvent()
|
||||
{
|
||||
Event.current.Use();
|
||||
}
|
||||
|
||||
public void Repaint()
|
||||
{
|
||||
HandleUtility.Repaint();
|
||||
}
|
||||
|
||||
public bool HasCurrentCamera()
|
||||
{
|
||||
return Camera.current != null;
|
||||
}
|
||||
|
||||
public float GetHandleSize(Vector3 position)
|
||||
{
|
||||
var scale = HasCurrentCamera() ? 0.01f : 0.05f;
|
||||
return HandleUtility.GetHandleSize(position) * scale;
|
||||
}
|
||||
|
||||
public float DistanceToSegment(Vector3 p1, Vector3 p2)
|
||||
{
|
||||
p1 = HandleUtility.WorldToGUIPoint(p1);
|
||||
p2 = HandleUtility.WorldToGUIPoint(p2);
|
||||
|
||||
return HandleUtility.DistancePointToLineSegment(Event.current.mousePosition, p1, p2);
|
||||
}
|
||||
|
||||
public float DistanceToCircle(Vector3 center, float radius)
|
||||
{
|
||||
return HandleUtility.DistanceToCircle(center, radius);
|
||||
}
|
||||
|
||||
public Vector3 GUIToWorld(Vector2 guiPosition, Vector3 planeNormal, Vector3 planePos)
|
||||
{
|
||||
Vector3 worldPos = Handles.inverseMatrix.MultiplyPoint(guiPosition);
|
||||
|
||||
if (Camera.current)
|
||||
{
|
||||
Ray ray = HandleUtility.GUIPointToWorldRay(guiPosition);
|
||||
|
||||
planeNormal = Handles.matrix.MultiplyVector(planeNormal);
|
||||
|
||||
planePos = Handles.matrix.MultiplyPoint(planePos);
|
||||
|
||||
Plane plane = new Plane(planeNormal, planePos);
|
||||
|
||||
float distance = 0f;
|
||||
|
||||
if (plane.Raycast(ray, out distance))
|
||||
{
|
||||
worldPos = Handles.inverseMatrix.MultiplyPoint(ray.GetPoint(distance));
|
||||
}
|
||||
}
|
||||
|
||||
return worldPos;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a6ffe588dbbb4714695514536c29df95
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,124 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path.GUIFramework
|
||||
{
|
||||
public class GUISystem
|
||||
{
|
||||
private readonly int kControlIDCheckHashCode = "ControlIDCheckHashCode".GetHashCode();
|
||||
|
||||
private List<Control> m_Controls = new List<Control>();
|
||||
private List<GUIAction> m_Actions = new List<GUIAction>();
|
||||
private IGUIState m_GUIState;
|
||||
private int m_PrevNearestControl = -1;
|
||||
private LayoutData m_PrevNearestLayoutData = LayoutData.zero;
|
||||
private int m_ControlIDCheck = -1;
|
||||
|
||||
public GUISystem(IGUIState guiState)
|
||||
{
|
||||
m_GUIState = guiState;
|
||||
}
|
||||
|
||||
public void AddControl(Control control)
|
||||
{
|
||||
if (control == null)
|
||||
throw new NullReferenceException("Control is null");
|
||||
|
||||
m_Controls.Add(control);
|
||||
}
|
||||
|
||||
public void RemoveControl(Control control)
|
||||
{
|
||||
m_Controls.Remove(control);
|
||||
}
|
||||
|
||||
public void AddAction(GUIAction action)
|
||||
{
|
||||
if (action == null)
|
||||
throw new NullReferenceException("Action is null");
|
||||
|
||||
m_Actions.Add(action);
|
||||
}
|
||||
|
||||
public void RemoveAction(GUIAction action)
|
||||
{
|
||||
m_Actions.Remove(action);
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
var controlIDCheck = m_GUIState.GetControlID(kControlIDCheckHashCode, FocusType.Passive);
|
||||
|
||||
if (m_GUIState.eventType == EventType.Layout)
|
||||
m_ControlIDCheck = controlIDCheck;
|
||||
else if (m_GUIState.eventType != EventType.Used && m_ControlIDCheck != controlIDCheck)
|
||||
Debug.LogWarning("GetControlID at event " + m_GUIState.eventType + " returns a controlID different from the one in Layout event");
|
||||
|
||||
var nearestLayoutData = LayoutData.zero;
|
||||
|
||||
foreach (var control in m_Controls)
|
||||
control.GetControl(m_GUIState);
|
||||
|
||||
if (m_GUIState.eventType == EventType.Layout)
|
||||
{
|
||||
foreach (var control in m_Controls)
|
||||
control.BeginLayout(m_GUIState);
|
||||
|
||||
foreach (var control in m_Controls)
|
||||
{
|
||||
control.Layout(m_GUIState);
|
||||
nearestLayoutData = LayoutData.Nearest(nearestLayoutData, control.layoutData);
|
||||
}
|
||||
|
||||
foreach (var control in m_Controls)
|
||||
m_GUIState.AddControl(control.ID, control.layoutData.distance);
|
||||
|
||||
foreach (var control in m_Controls)
|
||||
control.EndLayout(m_GUIState);
|
||||
|
||||
if (m_PrevNearestControl == m_GUIState.nearestControl)
|
||||
{
|
||||
if (nearestLayoutData.index != m_PrevNearestLayoutData.index)
|
||||
m_GUIState.Repaint();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PrevNearestControl = m_GUIState.nearestControl;
|
||||
m_GUIState.Repaint();
|
||||
}
|
||||
|
||||
m_PrevNearestLayoutData = nearestLayoutData;
|
||||
}
|
||||
|
||||
if (m_GUIState.eventType == EventType.Repaint)
|
||||
{
|
||||
foreach (var action in m_Actions)
|
||||
if (action.IsRepaintEnabled(m_GUIState))
|
||||
action.PreRepaint(m_GUIState);
|
||||
|
||||
foreach (var control in m_Controls)
|
||||
control.Repaint(m_GUIState);
|
||||
}
|
||||
|
||||
var repaintOnMouseMove = false;
|
||||
|
||||
foreach (var action in m_Actions)
|
||||
{
|
||||
if (IsMouseMoveEvent())
|
||||
repaintOnMouseMove |= action.IsRepaintOnMouseMoveEnabled(m_GUIState);
|
||||
|
||||
action.OnGUI(m_GUIState);
|
||||
}
|
||||
|
||||
if (repaintOnMouseMove)
|
||||
m_GUIState.Repaint();
|
||||
}
|
||||
|
||||
private bool IsMouseMoveEvent()
|
||||
{
|
||||
return m_GUIState.eventType == EventType.MouseMove || m_GUIState.eventType == EventType.MouseDrag;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: be957506ccdeb4a4789fd53667da3649
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,99 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path.GUIFramework
|
||||
{
|
||||
public class GenericControl : Control
|
||||
{
|
||||
public Func<IGUIState, LayoutData> onBeginLayout;
|
||||
public Action<IGUIState> onEndLayout;
|
||||
public Action<IGUIState, Control, int> onRepaint;
|
||||
public Func<int> count;
|
||||
public Func<int, Vector3> position;
|
||||
public Func<IGUIState, int, float> distance;
|
||||
public Func<int, Vector3> forward;
|
||||
public Func<int, Vector3> up;
|
||||
public Func<int, Vector3> right;
|
||||
public Func<int, object> userData;
|
||||
|
||||
public GenericControl(string name) : base(name)
|
||||
{
|
||||
}
|
||||
|
||||
protected override int GetCount()
|
||||
{
|
||||
if (count != null)
|
||||
return count();
|
||||
|
||||
return base.GetCount();
|
||||
}
|
||||
|
||||
protected override void OnEndLayout(IGUIState guiState)
|
||||
{
|
||||
if (onEndLayout != null)
|
||||
onEndLayout(guiState);
|
||||
}
|
||||
|
||||
protected override void OnRepaint(IGUIState guiState, int index)
|
||||
{
|
||||
if (onRepaint != null)
|
||||
onRepaint(guiState, this, index);
|
||||
}
|
||||
|
||||
protected override LayoutData OnBeginLayout(LayoutData data, IGUIState guiState)
|
||||
{
|
||||
if (onBeginLayout != null)
|
||||
return onBeginLayout(guiState);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
protected override Vector3 GetPosition(IGUIState guiState, int index)
|
||||
{
|
||||
if (position != null)
|
||||
return position(index);
|
||||
|
||||
return base.GetPosition(guiState,index);
|
||||
}
|
||||
|
||||
protected override float GetDistance(IGUIState guiState, int index)
|
||||
{
|
||||
if (distance != null)
|
||||
return distance(guiState, index);
|
||||
|
||||
return base.GetDistance(guiState, index);
|
||||
}
|
||||
|
||||
protected override Vector3 GetForward(IGUIState guiState, int index)
|
||||
{
|
||||
if (forward != null)
|
||||
return forward(index);
|
||||
|
||||
return base.GetForward(guiState,index);
|
||||
}
|
||||
|
||||
protected override Vector3 GetUp(IGUIState guiState, int index)
|
||||
{
|
||||
if (up != null)
|
||||
return up(index);
|
||||
|
||||
return base.GetUp(guiState,index);
|
||||
}
|
||||
|
||||
protected override Vector3 GetRight(IGUIState guiState, int index)
|
||||
{
|
||||
if (right != null)
|
||||
return right(index);
|
||||
|
||||
return base.GetRight(guiState,index);
|
||||
}
|
||||
|
||||
protected override object GetUserData(IGUIState guiState, int index)
|
||||
{
|
||||
if (userData != null)
|
||||
return userData(index);
|
||||
|
||||
return base.GetUserData(guiState,index);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 42c4e70b47496ce448cebce5780a4a58
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,58 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.U2D.Path.GUIFramework
|
||||
{
|
||||
public class GenericDefaultControl : DefaultControl
|
||||
{
|
||||
public Func<IGUIState, Vector3> position;
|
||||
public Func<IGUIState, Vector3> forward;
|
||||
public Func<IGUIState, Vector3> up;
|
||||
public Func<IGUIState, Vector3> right;
|
||||
public Func<IGUIState, object> userData;
|
||||
|
||||
public GenericDefaultControl(string name) : base(name)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Vector3 GetPosition(IGUIState guiState, int index)
|
||||
{
|
||||
if (position != null)
|
||||
return position(guiState);
|
||||
|
||||
return base.GetPosition(guiState, index);
|
||||
}
|
||||
|
||||
protected override Vector3 GetForward(IGUIState guiState, int index)
|
||||
{
|
||||
if (forward != null)
|
||||
return forward(guiState);
|
||||
|
||||
return base.GetForward(guiState, index);
|
||||
}
|
||||
|
||||
protected override Vector3 GetUp(IGUIState guiState, int index)
|
||||
{
|
||||
if (up != null)
|
||||
return up(guiState);
|
||||
|
||||
return base.GetUp(guiState, index);
|
||||
}
|
||||
|
||||
protected override Vector3 GetRight(IGUIState guiState, int index)
|
||||
{
|
||||
if (right != null)
|
||||
return right(guiState);
|
||||
|
||||
return base.GetRight(guiState, index);
|
||||
}
|
||||
|
||||
protected override object GetUserData(IGUIState guiState, int index)
|
||||
{
|
||||
if (userData != null)
|
||||
return userData(guiState);
|
||||
|
||||
return base.GetUserData(guiState, index);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 95695db3b2c152a4699bcb541136dc49
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|