chore: initial commit

This commit is contained in:
2026-05-08 11:04:00 +08:00
commit f55d2a57c3
6278 changed files with 866081 additions and 0 deletions

View File

@@ -0,0 +1,239 @@
using System;
using UnityEditor;
using UnityEngine;
namespace PathBerserker2d
{
internal static class GizmosDrawingExtensions
{
public static void DrawArrowHead(Vector2 basePos, Vector2 dir, float size)
{
dir.Normalize();
Vector2 normal = new Vector2(-dir.y, dir.x) * size;
Gizmos.DrawLine(basePos - normal, basePos + normal);
Gizmos.DrawLine(basePos - normal, basePos + dir * size);
Gizmos.DrawLine(basePos + normal, basePos + dir * size);
}
public static void DrawArrowHeadFromSpike(Vector2 pointyPos, Vector2 dir, float size)
{
dir.Normalize();
pointyPos -= dir * size;
Vector2 normal = new Vector2(-dir.y, dir.x) * size;
Gizmos.DrawLine(pointyPos - normal, pointyPos + normal);
Gizmos.DrawLine(pointyPos - normal, pointyPos + dir * size);
Gizmos.DrawLine(pointyPos + normal, pointyPos + dir * size);
}
public static void DrawArrow(Vector2 start, Vector2 end, float size)
{
Vector2 dir = end - start;
float length = dir.magnitude;
dir /= length;
Vector3 end3 = new Vector3(end.x, end.y);
Gizmos.DrawLine(start, end3);
Vector2 normal = new Vector2(-dir.y, dir.x) * size;
Vector2 baseA = start + dir * (length - size);
Gizmos.DrawLine(baseA - normal, end3);
Gizmos.DrawLine(baseA + normal, end3);
}
public static void DrawCircle(Vector2 center, float radius = 0.05f)
{
int segmentCount = 10;
Vector2 prevPoint = center + Vector2.up * radius;
for (float t = 1; t <= segmentCount; t++)
{
float x = (t / segmentCount) * Mathf.PI * 2.0f;
float cx = Mathf.Sin(x);
float cy = Mathf.Cos(x);
Vector2 point = center + new Vector2(cx, cy) * radius;
Gizmos.DrawLine(prevPoint, point);
prevPoint = point;
}
Gizmos.DrawLine(prevPoint, center + Vector2.up * radius);
}
public static void DrawBezierConnection(Vector2 start, Vector2 end, bool biDirectional)
{
Vector2 cp;
var tangent = (end - start);
var length = tangent.magnitude;
var normal = new Vector2(-tangent.y, tangent.x) / length;
cp = start + tangent * 0.5f + normal * (length / 5f);
DrawBezierConnection(start, end, cp, biDirectional);
}
public static void DrawBezierConnection(Vector2 start, Vector2 end, Vector2 cp, bool biDirectional)
{
float arcLength = (Vector2.Distance(end, start) * 2 + Vector2.Distance(end, cp) + Vector2.Distance(start, cp)) / 3f;
int numberOfSegments = Mathf.CeilToInt(arcLength) + 4;
Vector2 prev = start;
float t;
for (t = 1; t <= numberOfSegments; t++)
{
Vector2 v = QuadraticBezierCurve(t / numberOfSegments, start, cp, end);
Gizmos.DrawLine(prev, v);
prev = v;
}
//draw arrows
t = (numberOfSegments - 1) / (float)numberOfSegments;
Vector2 dir = end - QuadraticBezierCurve(t, start, cp, end);
DrawArrowHeadFromSpike(end, dir, 0.2f);
if (biDirectional)
{
dir = start - QuadraticBezierCurve(1f / numberOfSegments, start, cp, end);
DrawArrowHeadFromSpike(start, dir, 0.2f);
}
}
public static void DrawBezierConnectionWithOffset(Vector2 start, Vector2 end, Vector2 cp, Vector2 offset)
{
float arcLength = (Vector2.Distance(end, start) * 2 + Vector2.Distance(end, cp) + Vector2.Distance(start, cp)) / 3f;
int numberOfSegments = Mathf.CeilToInt(arcLength);
Vector2 prev = start + offset;
Gizmos.DrawLine(start, prev);
float t;
for (t = 1; t <= numberOfSegments; t++)
{
Vector2 v = QuadraticBezierCurve(t / numberOfSegments, start, cp, end) + offset;
Gizmos.DrawLine(v, v - offset);
Gizmos.DrawLine(prev, v);
prev = v;
}
}
public static void DrawProjectileArc(Vector2 start, Vector2 end, float hSpeed, bool isBidiretional)
{
float hDelta = end.x - start.x;
float t = hDelta / hSpeed;
int numberOfSegments = Mathf.CeilToInt(t) + 4;
float p0 = start.y - end.y;
float v0 = 9.81f * t * 0.5f - p0 / t;
Func<float, float> func = x => 0.5f * -9.81f * x * x + v0 * x + p0;
Vector2 prev = start;
float z;
float timePerSegment = t / numberOfSegments;
for (z = 1; z <= numberOfSegments; z++)
{
Vector2 v = new Vector2(start.x + z * timePerSegment * hSpeed, end.y + func(z * timePerSegment));
Gizmos.DrawLine(prev, v);
prev = v;
}
Vector2 dir = end - new Vector2(start.x + (numberOfSegments - 1) * timePerSegment * hSpeed, end.y + func((numberOfSegments - 1) * timePerSegment));
DrawArrowHeadFromSpike(end, dir, 0.2f);
if (isBidiretional)
{
dir = start - new Vector2(start.x + timePerSegment * hSpeed, end.y + func(timePerSegment));
DrawArrowHeadFromSpike(start, dir, 0.2f);
}
}
public static void DrawJumpArc(Vector2 start, Vector2 end, float jumpSpeed, bool isBidiretional)
{
Vector2 dir = end - start;
float distance = dir.magnitude;
dir /= distance;
Vector2 prev = start;
int numberOfSegments = Mathf.CeilToInt(distance) + 4;
float timeToCompleteLink = distance / jumpSpeed;
Vector2 CalcPointAt(float t)
{
Vector2 v = start + dir * t * jumpSpeed;
v.y += distance * 0.3f * Mathf.Sin(Mathf.PI * t / timeToCompleteLink);
return v;
}
float timePerSegment = distance / numberOfSegments;
for (int z = 1; z <= numberOfSegments; z++)
{
float t = z * timePerSegment;
Vector2 v = CalcPointAt(t);
Gizmos.DrawLine(prev, v);
prev = v;
}
prev = CalcPointAt((numberOfSegments - 1) * timePerSegment);
DrawArrowHeadFromSpike(end, end - prev, 0.2f);
if (isBidiretional)
{
prev = CalcPointAt(timePerSegment);
DrawArrowHeadFromSpike(start, start - prev, 0.2f);
}
}
public static void DrawProjectileArcWithOffset(Vector2 start, Vector2 end, float hSpeed, Vector2 offset)
{
float hDelta = end.x - start.x;
float t = hDelta / hSpeed;
int numberOfSegments = Mathf.CeilToInt(t) + 4;
float p0 = start.y - end.y;
float v0 = 9.81f * t * 0.5f - p0 / t;
Func<float, float> func = x => 0.5f * -9.81f * x * x + v0 * x + p0;
Vector2 prev = start + offset;
Gizmos.DrawLine(start, prev);
float z;
float timePerSegment = t / numberOfSegments;
for (z = 1; z <= numberOfSegments; z++)
{
Vector2 v = new Vector2(start.x + z * timePerSegment * hSpeed, end.y + func(z * timePerSegment)) + offset;
Gizmos.DrawLine(prev, v);
Gizmos.DrawLine(v, v - offset);
prev = v;
}
}
private static Vector2 QuadraticBezierCurve(float t, Vector2 a, Vector2 b, Vector2 c)
{
return (1 - t) * (1 - t) * a + 2 * (1 - t) * t * b + t * t * c;
}
public static Color LinearBlendBetweenColors(float value, params Color[] colors)
{
value = Mathf.Clamp01(value);
int index = (int)(value * (colors.Length - 1));
float t = (value * (colors.Length - 1)) - index;
Color b = index >= colors.Length - 1 ? colors[index] : colors[index + 1];
return Color.Lerp(colors[index], b, t);
}
public static void DrawRect(Vector2 position, Vector2 size)
{
Gizmos.DrawLine(position + size, new Vector3(position.x, position.y + size.y));
Gizmos.DrawLine(position, new Vector3(position.x, position.y + size.y));
Gizmos.DrawLine(position + size, new Vector3(position.x + size.x, position.y));
Gizmos.DrawLine(position, new Vector3(position.x + size.x, position.y));
}
public static void DrawRect(Rect rect)
{
Gizmos.DrawLine(rect.position + rect.size, new Vector3(rect.position.x, rect.position.y + rect.size.y));
Gizmos.DrawLine(rect.position, new Vector3(rect.position.x, rect.position.y + rect.size.y));
Gizmos.DrawLine(rect.position + rect.size, new Vector3(rect.position.x + rect.size.x, rect.position.y));
Gizmos.DrawLine(rect.position, new Vector3(rect.position.x + rect.size.x, rect.position.y));
}
public static void SetColor(Color color)
{
Handles.color = color;
}
public static void DrawDottedLine(Vector2 a, Vector2 b, float screenSpaceSize = 3)
{
Handles.DrawDottedLine(a, b, screenSpaceSize);
}
}
}

View File

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

View File

@@ -0,0 +1,94 @@
using UnityEditor;
using UnityEngine;
namespace PathBerserker2d
{
internal static class NavAgentDrawer
{
[DrawGizmo(GizmoType.Selected | GizmoType.Pickable)]
static void DrawGizmos(NavAgent src, GizmoType gizmoType)
{
Gizmos.color = Color.green;
if (!Application.IsPlaying(src))
{
Vector2 adjustedPosition = src.transform.position;
Gizmos.DrawRay(adjustedPosition, src.transform.up * src.Height);
Gizmos.DrawLine(adjustedPosition + -(Vector2)src.transform.right * 0.2f, adjustedPosition + (Vector2)src.transform.right * 0.2f);
}
else if(!src.currentMappedPosition.IsInvalid())
{
Gizmos.color = Color.magenta;
GizmosDrawingExtensions.DrawCircle( src.currentMappedPosition.Position);
}
if (src.IsFollowingAPath)
{
int hash = Mathf.Abs(src.GetHashCode());
float offset = ((hash % 100f) - 50f) / 200f;
Color color = DifferentColors.GetColor(hash);
if (src.IsOnLink)
{
DrawPath(src.Path, src.Path.Current.LinkStart, src.Height / 2f + offset, color);
}
else
{
DrawPath(src.Path, src.transform.position, src.Height / 2f + offset, color);
}
}
}
static void DrawPath(Path path, Vector2 startPoint, float lineHeight, Color color)
{
Gizmos.color = color;
var seg = path.Current;
Vector2 lineA = startPoint + seg.Normal * lineHeight;
while (seg != null)
{
Vector2 lineB = seg.LinkStart + seg.Normal * lineHeight;
if (seg.Next == null)
{
Gizmos.DrawLine(lineA, lineB);
lineA = lineB;
GizmosDrawingExtensions.DrawCircle(lineB, 0.2f);
GizmosDrawingExtensions.DrawCircle(lineB, 0.3f);
}
else
{
if (seg.link.LinkType == -1)
{
Vector2 oLineA = seg.LinkEnd + seg.Next.Normal * lineHeight;
Vector2 oLineB = seg.Next.LinkStart + seg.Next.Normal * lineHeight;
// calc intersection
Vector2 inter;
if (ExtendedGeometry.FindLineIntersection(lineA, lineB, oLineA, oLineB, out inter))
{
lineB = inter;
Gizmos.DrawLine(lineA, lineB);
lineA = lineB;
}
else
{
Gizmos.DrawLine(lineB, oLineA);
Gizmos.DrawLine(lineA, lineB);
lineA = oLineA;
}
}
else
{
Gizmos.DrawLine(lineA, lineB);
lineA = lineB;
lineB = seg.LinkEnd + seg.Next.Normal * lineHeight;
Gizmos.DrawLine(lineA, lineB);
lineA = lineB;
}
}
seg = seg.Next;
}
}
}
}

View File

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

View File

@@ -0,0 +1,29 @@
using UnityEditor;
using UnityEngine;
namespace PathBerserker2d
{
internal static class NavAreaMarkerDrawer
{
static Vector3[] worldCorners = new Vector3[4];
[DrawGizmo(GizmoType.Selected | GizmoType.NonSelected | GizmoType.Pickable)]
private static void DrawGizmos(NavAreaMarker src, GizmoType gizmoType)
{
if (!Application.IsPlaying(src) && ((gizmoType & GizmoType.Selected) != 0 || PathBerserker2dSettings.DrawUnselectedAreaMarkers))
{
var rT = src.GetComponent<RectTransform>();
Color c = src.MarkerColor;
c.a = 0.4f;
SharedMaterials.UnlitTransparentTinted.SetColor(SharedMaterials.UnlitTransparentTinted_ColorId, c);
SharedMaterials.UnlitTransparentTinted.SetPass(0);
var m = rT.localToWorldMatrix * Matrix4x4.TRS(rT.rect.min, Quaternion.identity, rT.rect.size);
m.m23 = 2;
Graphics.DrawMeshNow(PrimitiveMesh.Quad, m);
}
}
}
}

View File

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

View File

@@ -0,0 +1,56 @@
using UnityEngine;
namespace PathBerserker2d
{
internal static class NavGraphDrawer
{
public static void Draw(NavGraph graph)
{
Matrix4x4 oldMatrix = Gizmos.matrix;
Gizmos.matrix = Matrix4x4.identity;
SharedMaterials.UnlitStripped.SetFloat(SharedMaterials.UnlitStripped_SegmentSizeId, 0.08f);
SharedMaterials.UnlitStripped.SetFloat(SharedMaterials.UnlitStripped_PauseSizeId, 0.08f * (PathBerserker2dSettings.NavTags.Length - 2));
// draw segments
foreach (var pair in graph.segmentTrees)
{
foreach (var cluster in pair.Value.Clusters)
{
DrawCluster(cluster, pair.Value.WorldToLocal.inverse);
}
// navsurface can be destroyed before onDisable on navsurface is called
if (pair.Key != null)
NavSurfaceDrawer.DrawNavSurface(pair.Key);
}
Gizmos.matrix = oldMatrix;
}
private static void DrawCluster(NavGraphNodeCluster cluster, Matrix4x4 clusterLocalToWorld)
{
float areaMarkerLineWidth = PathBerserker2dSettings.NavAreaMarkerLineWidth;
foreach (var mod in cluster.modifiers)
{
Vector2 a = cluster.GetPositionAlongSegment(mod.T);
Vector2 b = cluster.GetPositionAlongSegment(mod.T + mod.Length);
Vector2 tangent = b - a;
Quaternion rot = Quaternion.Euler(0, 0, Vector2.SignedAngle(Vector2.right, tangent));
SharedMaterials.UnlitStripped.SetFloat(SharedMaterials.UnlitStripped_XOffsetId, 0.08f * mod.NavTag);
SharedMaterials.UnlitStripped.SetColor(SharedMaterials.UnlitStripped_ColorId, PathBerserker2dSettings.GetNavTagColor(mod.NavTag));
SharedMaterials.UnlitStripped.SetPass(0);
Graphics.DrawMeshNow(PrimitiveMesh.Quad, clusterLocalToWorld * Matrix4x4.TRS(a, rot, new Vector3(tangent.magnitude, areaMarkerLineWidth)));
}
for (int iNode = 0; iNode < cluster.nodes.Count; iNode++)
{
var node = cluster.nodes[iNode];
var link = node.link;
if (link.LinkType > 0)
NavLinkInstanceDrawer.Draw(link, cluster.owner.LocalToWorld.MultiplyPoint3x4(cluster.GetPositionAlongSegment(node.t)),
node.LinkTarget.owner.LocalToWorld.MultiplyPoint3x4(node.LinkTarget.GetPositionAlongSegment(node.LinkTargetT)));
}
}
}
}

View File

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

View File

@@ -0,0 +1,60 @@
using UnityEditor;
using UnityEngine;
using static PathBerserker2d.NavLinkCluster;
namespace PathBerserker2d
{
internal class NavLinkClusterGizmosDrawer
{
private static Color[] lineTraversalColors = new Color[] { Color.red, Color.green, Color.blue };
[DrawGizmo(GizmoType.Selected | GizmoType.NonSelected | GizmoType.Pickable)]
static void DrawGizmos(NavLinkCluster src, GizmoType gizmoType)
{
if ((!PathBerserker2dSettings.DrawUnselectedLinks || (gizmoType & GizmoType.Selected) != 0))
{
Gizmos.DrawIcon(src.transform.position, "PathBerserker2D/link_icon.png");
}
if ((gizmoType & GizmoType.Selected) != 0 || (PathBerserker2dSettings.DrawUnselectedLinks &&
!Application.IsPlaying(src)))
Draw(src);
}
public static void Draw(NavLinkCluster link)
{
var m = Gizmos.matrix;
Gizmos.matrix = Matrix4x4.Translate(new Vector3(0, 0, link.transform.position.z));
Gizmos.color = Color.green;
GizmosDrawingExtensions.DrawCircle(link.transform.position);
Gizmos.color = Color.white;
foreach (var points in link.LinkPoints)
{
Vector2 worldPoint = link.transform.TransformPoint(points.point);
Gizmos.color = PathBerserker2dSettings.NavLinkTypeColors[link.LinkType];
Gizmos.DrawLine((Vector2)link.transform.position, worldPoint);
Vector2 dir = ((Vector2)link.transform.position - worldPoint).normalized;
Gizmos.color = lineTraversalColors[(int)points.traversalType];
if (points.traversalType == PointTraversalType.Entry || points.traversalType == PointTraversalType.Both)
{
GizmosDrawingExtensions.DrawArrowHead(worldPoint, dir, 0.2f);
if (points.traversalType == PointTraversalType.Exit || points.traversalType == PointTraversalType.Both)
GizmosDrawingExtensions.DrawArrowHead(worldPoint + dir * 0.2f, -dir, 0.2f);
}
else if (points.traversalType == PointTraversalType.Exit || points.traversalType == PointTraversalType.Both)
GizmosDrawingExtensions.DrawArrowHead(worldPoint, -dir, 0.2f);
}
Gizmos.matrix = m;
if (link.LinkTypeName == "climb")
{
Vector3 pos = link.gameObject.transform.position;
Vector3 dir = link.gameObject.transform.up;
Gizmos.color = Color.grey;
Gizmos.DrawLine(pos - dir * 0.5f * 2, pos + dir * 0.5f * 2);
}
}
}
}

View File

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

View File

@@ -0,0 +1,129 @@
using UnityEditor;
using UnityEngine;
using static PathBerserker2d.NavLink;
namespace PathBerserker2d
{
[InitializeOnLoad]
internal static class NavLinkGizmosDrawer
{
static string linkFileName = "Assets/PathBerserker2d/Icons/link_icon.png";
static Texture2D linkTexture;
static NavLinkGizmosDrawer()
{
linkTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(linkFileName);
}
[DrawGizmo(GizmoType.Selected | GizmoType.NonSelected | GizmoType.Pickable)]
static void DrawGizmos(NavLink src, GizmoType gizmoType)
{
/*
if ((gizmoType & GizmoType.Selected) != 0 || PathBerserker2dSettings.DrawUnselectedLinks)
{
if (src.CurrentVisualizationType == NavLink.VisualizationType.Teleport)
{
Gizmos.DrawIcon(src.StartWorldPosition, "PathBerserker2d/Gizmos/portal.png");
Gizmos.DrawIcon(src.GoalWorldPosition, "PathBerserker2D/portal.png");
}
else
{
//Gizmos.DrawIcon((src.GoalWorldPosition - src.StartWorldPosition) * 0.5f + src.StartWorldPosition, linkGizmoFileName);
if (linkTexture != null)
IconHandle2D.DrawHandle((src.GoalWorldPosition - src.StartWorldPosition) * 0.5f + src.StartWorldPosition, linkTexture, 0.5f, src);
}
}
*/
bool isSelected = (gizmoType & GizmoType.Selected) != 0;
if (isSelected || (PathBerserker2dSettings.DrawUnselectedLinks &&
!Application.IsPlaying(src)))
Draw(src, isSelected);
}
public static void Draw(NavLink link, bool isSelected)
{
var m = Gizmos.matrix;
Gizmos.matrix = Matrix4x4.Translate(new Vector3(0, 0, link.transform.position.z));
Gizmos.color = PathBerserker2dSettings.GetLinkTypeColor(link.LinkType);
switch (link.CurrentVisualizationType)
{
case VisualizationType.Linear:
Vector2 dir = (link.GoalWorldPosition - link.StartWorldPosition).normalized;
if (link.IsBidirectional)
{
GizmosDrawingExtensions.DrawArrowHead(link.StartWorldPosition + dir * 0.2f, -dir, 0.2f);
}
else
{
Vector2 normal = new Vector2(-dir.y, dir.x) * 0.3f;
Gizmos.DrawLine(link.StartWorldPosition + normal, link.StartWorldPosition - normal);
}
Gizmos.DrawLine(link.StartWorldPosition, link.GoalWorldPosition);
GizmosDrawingExtensions.DrawArrowHead(link.GoalWorldPosition - dir * 0.2f, dir, 0.2f);
if (isSelected)
{
Vector2 offset = Quaternion.Euler(0, 0, link.TraversalAngle) * Vector3.up * link.Clearance;
Gizmos.color = Color.green;
Gizmos.DrawLine(link.StartWorldPosition + offset, link.GoalWorldPosition + offset);
float length = (link.GoalWorldPosition - link.StartWorldPosition).magnitude;
Gizmos.DrawLine(link.StartWorldPosition, link.StartWorldPosition + offset);
for (float t = 2; t <= length - 2; t += 2)
{
Gizmos.DrawLine(link.StartWorldPosition + dir * t, link.StartWorldPosition + offset + dir * t);
}
Gizmos.DrawLine(link.GoalWorldPosition, link.GoalWorldPosition + offset);
}
break;
case VisualizationType.QuadradticBezier:
GizmosDrawingExtensions.DrawBezierConnection(
link.StartWorldPosition,
link.GoalWorldPosition,
link.transform.TransformPoint(link.BezierControlPoint),
link.IsBidirectional);
if (isSelected)
{
Vector2 offset = Quaternion.Euler(0, 0, link.TraversalAngle) * Vector3.up * link.Clearance;
Gizmos.color = Color.green;
GizmosDrawingExtensions.DrawBezierConnectionWithOffset(
link.StartWorldPosition,
link.GoalWorldPosition,
(Vector2)link.transform.TransformPoint(link.BezierControlPoint),
offset);
}
break;
case VisualizationType.Projectile:
GizmosDrawingExtensions.DrawProjectileArc(link.StartWorldPosition, link.GoalWorldPosition, link.HorizontalSpeed, link.IsBidirectional);
if (isSelected)
{
Vector2 offset = Quaternion.Euler(0, 0, link.TraversalAngle) * Vector3.up * link.Clearance;
Gizmos.color = Color.green;
GizmosDrawingExtensions.DrawProjectileArcWithOffset(
link.StartWorldPosition, link.GoalWorldPosition, link.HorizontalSpeed,
offset);
}
break;
case VisualizationType.Teleport:
break;
case VisualizationType.TransformBasedMovement:
GizmosDrawingExtensions.DrawJumpArc(link.StartWorldPosition, link.GoalWorldPosition, link.HorizontalSpeed, link.IsBidirectional);
break;
}
Gizmos.matrix = m;
if (link.LinkTypeName == "climb")
{
Vector3 pos = link.gameObject.transform.position;
Vector3 dir = link.gameObject.transform.up;
Gizmos.color = Color.grey;
Gizmos.DrawLine(pos - dir * 0.5f * 2, pos + dir * 0.5f * 2);
}
}
}
}

View File

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

View File

@@ -0,0 +1,13 @@
using UnityEngine;
namespace PathBerserker2d
{
internal static class NavLinkInstanceDrawer
{
public static void Draw(INavLinkInstance link, Vector2 worldStartPos, Vector2 worldGoalPos)
{
Gizmos.color = PathBerserker2dSettings.GetLinkTypeColor(link.LinkType);
GizmosDrawingExtensions.DrawArrow(worldStartPos, worldGoalPos, 0.2f);
}
}
}

View File

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

View File

@@ -0,0 +1,28 @@
using UnityEditor;
using UnityEngine;
namespace PathBerserker2d
{
internal static class NavSegmentSubstractorDrawer
{
[DrawGizmo(GizmoType.Selected | GizmoType.NonSelected | GizmoType.Pickable)]
private static void DrawGizmos(NavSegmentSubstractor src, GizmoType gizmoType)
{
if ((gizmoType & GizmoType.Selected) != 0 || PathBerserker2dSettings.DrawUnselectedSubstractors)
{
Gizmos.color = Color.red;
var rT = src.GetComponent<RectTransform>();
var r = rT.rect;
Vector2 scaleFactor = rT.lossyScale * r.size * 0.5f;
Vector2 center = r.center;
r.min = center - scaleFactor + (Vector2)rT.position;
r.max = center + scaleFactor + (Vector2)rT.position;
GizmosDrawingExtensions.DrawRect(r);
Gizmos.DrawLine(r.max, r.min);
}
}
}
}

View File

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

View File

@@ -0,0 +1,135 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace PathBerserker2d
{
internal static class NavSurfaceDrawer
{
[DrawGizmo(GizmoType.Selected | GizmoType.NonSelected | GizmoType.Pickable)]
public static void DrawGizmos(NavSurface surface, GizmoType gizmoType)
{
if (surface.NavSegments != null && !Application.IsPlaying(surface) && (PathBerserker2dSettings.DrawUnselectedSurfaces || (gizmoType & GizmoType.Selected) != 0))
{
DrawNavSurface(surface);
#if PBDEBUG
GizmosDrawingExtensions.DrawRect(surface.WorldBounds);
#endif
}
}
private static bool[] visited;
private static Dictionary<NavSurface, List<Mesh>> miterLinesMap;
public static void DrawNavSurface(NavSurface surface)
{
if (miterLinesMap == null)
miterLinesMap = new Dictionary<NavSurface, List<Mesh>>();
List<Mesh> miterLines = null;
miterLinesMap.TryGetValue(surface, out miterLines);
if (surface.hasDataChanged || miterLines == null)
{
if (visited == null || visited.Length < surface.NavSegments.Count)
{
visited = new bool[surface.NavSegments.Count];
}
else
{
for (int i = 0; i < visited.Length; i++)
{
visited[i] = false;
}
}
var miterCreator = new MiterLineMeshCreator();
bool newMiterLines = miterLines == null;
if (newMiterLines)
miterLines = new List<Mesh>();
int lineCount = 0;
for (int i = 0; i < surface.NavSegments.Count; i++)
{
if (!visited[i])
{
var points = GatherContourPoints(surface, surface.NavSegments[i], ref visited);
if (lineCount >= miterLines.Count)
{
miterLines.Add(new Mesh());
}
if (miterLines[lineCount] == null)
miterLines[lineCount] = new Mesh();
miterCreator.CreateLine(miterLines[lineCount], points, PathBerserker2dSettings.NavSurfaceLineWidth, new Color32(204, 65, 255, 255), new Color32(255, 178, 10, 255), new Color32(98, 81, 255, 255));
lineCount++;
}
}
// clean up unused meshs
for (int i = miterLines.Count - 1; i >= lineCount; i--)
{
GameObject.DestroyImmediate(miterLines[i]);
miterLines.RemoveAt(i);
}
if (newMiterLines)
miterLinesMap.Add(surface, miterLines);
surface.hasDataChanged = false;
}
SharedMaterials.UnlitVertexColorSolid.SetPass(0);
if (miterLines.Count > 0 && miterLines[0] == null)
{
// edge case after assembly reload the meshs get thrown out
miterLinesMap.Clear();
return;
}
foreach (var ml in miterLines)
{
Graphics.DrawMeshNow(ml, surface.LocalToWorldMatrixEditor);
}
}
private static List<Vector2> GatherContourPoints(NavSurface surface, NavSegment initialSeg, ref bool[] visited)
{
List<Vector2> contourPoints = new List<Vector2>();
if (!initialSeg.HasPrev)
{
contourPoints.Add(initialSeg.Start);
}
contourPoints.Add(initialSeg.End);
NavSegment seg = initialSeg;
while (seg.HasNext && !visited[seg.NextSegmentIndex])
{
visited[seg.NextSegmentIndex] = true;
seg = surface.NavSegments[seg.NextSegmentIndex];
contourPoints.Add(seg.End);
}
if (initialSeg.HasPrev && !visited[initialSeg.PrevSegmentIndex])
{
// we might have missed segments to the left get em
List<Vector2> leftPoints = new List<Vector2>();
seg = initialSeg;
while (seg.HasPrev)
{
visited[seg.PrevSegmentIndex] = true;
seg = surface.NavSegments[seg.PrevSegmentIndex];
leftPoints.Add(seg.End);
}
leftPoints.Add(seg.Start);
leftPoints.Reverse();
leftPoints.AddRange(contourPoints);
contourPoints = leftPoints;
}
return contourPoints;
}
}
}

View File

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

View File

@@ -0,0 +1,17 @@
using UnityEditor;
using UnityEngine;
namespace PathBerserker2d
{
internal class PBWorldDrawer
{
[DrawGizmo(GizmoType.Selected | GizmoType.NonSelected | GizmoType.Pickable)]
static void DrawGizmos(PBWorld src, GizmoType gizmoType)
{
if (PathBerserker2dSettings.DrawGraphWhilePlaying && PBWorld.NavGraph != null)
{
NavGraphDrawer.Draw(PBWorld.NavGraph);
}
}
}
}

View File

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